Match
match compares a value against a list of patterns and runs the code for the first one that fits.
match
Each arm is pattern => expression. Rust checks the arms from top to bottom and stops at the first match.
enum Coin { Penny, Dime }let c = Coin::Dime;let cents = match c { Coin::Penny => 1, Coin::Dime => 10,};match is an expression, so it gives back a value. Every arm must give the same type.
Exhaustive matching
A match must cover every possible value. If you forget a variant, the code does not compile (error E0004). This means adding a new variant later shows you every match you need to update.
Binding in patterns
A pattern can pull data out of a variant into a new variable. The variable only exists inside that arm.
let n: Option<i32> = Some(5);match n { Some(x) => println!("got {x}"), None => println!("nothing"),}Wildcards, | and ranges
_matches anything and ignores it. Put it last, as a catch-all.|lets one arm match several patterns.1..=5matches any number from 1 to 5.
let n = 7;let msg = match n { 0 => "zero", 1 | 2 => "small", 3..=9 => "medium", _ => "big",};Numbers have too many values to list, so a match on a number almost always needs _.
if let
When you only care about one pattern, if let is shorter than match.
if let Some(x) = n { println!("got {x}");}You can add an else for everything else.
Remember
- The first arm that fits wins.
- Cover every case, or use
_(E0004 otherwise). - Names in a pattern only live inside that arm.
- Use
if letfor one pattern.