Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler allow pattern matching an enum in a function argument if it will never work and are there places pattern matching is useful?

Tags:

rust

While looking at this axum crate example, I noticed a weird syntax in the function signature:

async fn create_user(
    Json(payload): Json<CreateUser>,
) -> impl IntoResponse {
  // blah blah
}

I eventually understood that Json<T>(pub T) is a newtype struct and wrapping Json(payload) means that we're extracting the T - we don't care about Json<T>, only the contained T.

I tested this out:

fn baz(Some(value): Option<i32>) {
    println!("value = {}", value);
}

The compiler complains that None is not covered.

My questions are:

  • Why does the compiler accept this syntax for enums knowing that it will never work (i.e. there will always be a pattern that is not covered)?

  • Are there other places where pattern matching in function arguments is useful?

like image 809
Midnight Exigent Avatar asked Nov 16 '25 10:11

Midnight Exigent


1 Answers

There is a distinction between refutable and irrefutable patterns.

You probably understand refutable patterns, i.e. patterns that can fail to match. These are typically tied to conditionals:

  • if let <PAT> = ...
  • match ... { <PAT> => ... }
  • while <PAT> = ...

However, irrefutable patterns are perhaps more prevalent.

  • let <PAT> = ...
  • for <PAT> in ...
  • fn f(<PAT>: ...)
  • |<PAT>| { ... }
  • basically anywhere you can declare a new variable is usually done via irrefutable patterns

You may understand their more advanced usage as "destructuring" or "structured bindings". Irrefutable patterns can:

  • introduce new variables: a
  • dereference: &a
  • destructure structs: { field1, field2, ... }
  • destructure tuples: (a, b)
  • destructure newtypes and single variant enums
  • immediately discard the value: _
  • mix all the above

This is explained further in Patterns and Matching in the Rust book.

So in essence, a pattern can go in place of a function parameter, but the pattern must not fail. Using patterns for destructuring struct fields or tuples is very common, though probably moreso for closures than functions.

like image 84
kmdreko Avatar answered Nov 18 '25 21:11

kmdreko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!