Pattern Matching
Using the match expression and pattern matching.
Pattern Matching
Pattern matching is one of Rust's most powerful features, allowing us to compare a value against different patterns.
Match Expression
RUSTmatch value { pattern1 => expression1, pattern2 => expression2, _ => default_case, }
Exhaustive Matching
The match must be exhaustive - all possible cases must be covered:
RUSTmatch coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, // If we omitted one, we'd get an error! }
Binding to Values
RUSTmatch value { Some(x) => println!("Value: {}", x), None => println!("No value"), }
If Let
Simplified syntax for handling a single case:
RUSTif let Some(3) = some_option_value { println!("three"); }
While Let
RUSTwhile let Some(top) = stack.pop() { println!("{}", top); }
Destructuring
RUSTlet (x, y) = point; let Point { x, y } = point;
Code Examples
Match Expression
Basic match usage
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
fn main() {
let coin = Coin::Quarter;
println!("Value: {} cents", value_in_cents(coin));
}Explanation:
The match expression must cover all possible enum variants. The compiler checks that all cases are handled.
Binding to Values
Extracting data with pattern matching
enum Option<T> {
Some(T),
None,
}
fn main() {
let some_number = Some(5);
match some_number {
Some(x) => println!("The value: {}", x),
None => println!("No value"),
}
let absent_number: Option<i32> = None;
match absent_number {
Some(x) => println!("The value: {}", x),
None => println!("No value"),
}
}Explanation:
Pattern matching allows us to directly bind data stored in enum variants to variables.
If Let
Using if let for simplified matching
fn main() {
let some_value = Some(3);
match some_value {
Some(3) => println!("three"),
_ => (),
}
if let Some(3) = some_value {
println!("three");
}
}Explanation:
The `if let` is a shortened syntax when we only want to handle one case. It does the same as a single match arm, but more concisely.
Exercises
Match Practice
Write a function that handles an Option<i32> with match!
Starter Code:
fn handle_option(value: Option<i32>) {
}
fn main() {
handle_option(Some(42));
handle_option(None);
}