Pattern Matching
The match
keyword lets you match a value against one or more patterns. The
comparisons are done from top to bottom and the first match wins.
The patterns can be simple values, similarly to switch
in C and C++:
#[rustfmt::skip] fn main() { let input = 'x'; match input { 'q' => println!("Quitting"), 'a' | 's' | 'w' | 'd' => println!("Moving around"), '0'..='9' => println!("Number input"), key if key.is_lowercase() => println!("Lowercase: {key}"), _ => println!("Something else"), } }
The _
pattern is a wildcard pattern which matches any value. The expressions
must be irrefutable, meaning that it covers every possibility, so _
is often
used as the final catch-all case.
Match can be used as an expression. Just like if
, each match arm must have the
same type. The type is the last expression of the block, if any. In the example
above, the type is ()
.
A variable in the pattern (key
in this example) will create a binding that can
be used within the match arm.
A match guard causes the arm to match only if the condition is true.
Key Points:
-
You might point out how some specific characters are being used when in a pattern
|
as anor
..
can expand as much as it needs to be1..=5
represents an inclusive range_
is a wild card
-
Match guards as a separate syntax feature are important and necessary when we wish to concisely express more complex ideas than patterns alone would allow.
-
They are not the same as separate
if
expression inside of the match arm. Anif
expression inside of the branch block (after=>
) happens after the match arm is selected. Failing theif
condition inside of that block won’t result in other arms of the originalmatch
expression being considered. -
The condition defined in the guard applies to every expression in a pattern with an
|
.