Rust Match
The match expression is Rust's pattern-matching control flow operator, and unlike a switch statement in other languages, the compiler forces you to account for every possible value up front.
Why match Instead of if/else
match compares a value against a series of patterns, top to bottom, and runs the first arm whose pattern fits. It supports exact values, ranges, multiple alternatives with |, and — unlike if/else chains — the compiler checks that every possible input value is handled.
Basic match on an integer
fn main() {
let dice_roll = 4;
match dice_roll {
1 => println!("Snake eyes... well, one die anyway."),
2 | 3 => println!("Low roll."),
4..=5 => println!("Decent roll."),
6 => println!("Maximum roll!"),
_ => println!("Not a valid six-sided die value."),
}
}Matching on Enums and Binding Data
match really shines with enums: it can destructure each variant and bind its inner data to local variables in the same pattern, so you never need a separate step to "unwrap" the value first.
Destructuring enum variants
enum Shape {
Circle(f64),
Rectangle(f64, f64),
Triangle { base: f64, height: f64 },
}
fn area(shape: &Shape) -> f64 {
match shape {
Shape::Circle(radius) => std::f64::consts::PI * radius * radius,
Shape::Rectangle(width, height) => width * height,
Shape::Triangle { base, height } => 0.5 * base * height,
}
}
fn main() {
let shapes = vec![
Shape::Circle(2.0),
Shape::Rectangle(3.0, 4.0),
Shape::Triangle { base: 6.0, height: 2.0 },
];
for shape in &shapes {
println!("Area: {:.2}", area(shape));
}
}Match Guards and Expression Position
match with guards, used as an expression
fn describe(n: i32) -> String {
match n {
n if n < 0 => String::from("negative"),
0 => String::from("zero"),
n if n % 2 == 0 => String::from("positive and even"),
_ => String::from("positive and odd"),
}
}
fn main() {
for n in [-3, 0, 4, 7] {
println!("{} -> {}", n, describe(n));
}
}- Arms are checked top to bottom, so put more specific patterns before general ones.
- Use _ to explicitly ignore values you don't need to inspect.
- match returns a value, so it can be a function's tail expression or the right-hand side of a let binding.
- Combine several values into one arm with the | operator.
Exercise: Rust Match
What does the Rust compiler require of a `match` expression's patterns?