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 (ie there will always be a pattern that is not covered)?
Are there other places where pattern matching in function arguments is useful?
There is a distinction between refutable and irrefutable patterns.
You probably understand refutable patterns, ie 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>| {... }
You may understand their more advanced usage as "destructuring" or "structured bindings". Irrefutable patterns can:
a
&a
{ field1, field2, ... }
(a, b)
_
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.