match / Pattern Matching
The match expression in Rust matches a value against multiple patterns and branches accordingly. Because all possible patterns must be covered, the compiler guarantees exhaustive handling. It supports guard conditions, bindings, range patterns, and more.
Syntax
// Basic match expression. All patterns must be covered.
match value {
pattern1 => expr1,
pattern2 => {
// Use a block for multiple statements.
expr2
}
_ => default_action, // Wildcard catches everything else.
}
// You can add a guard condition with if.
match n {
x if x < 0 => println!("negative"),
0 => println!("zero"),
_ => println!("positive"),
}
// Use @ to bind a matched value to a variable.
match n {
x @ 1..=10 => println!("in range 1–10: {}", x),
_ => println!("out of range"),
}
// Use | for OR patterns.
match c {
'a' | 'e' | 'i' | 'o' | 'u' => println!("vowel"),
_ => println!("consonant"),
}
Pattern Types
| Pattern | Description |
|---|---|
| Literal (42, "hello", true) | Matches when the value is exactly equal. |
| Variable (x) | Matches any value and binds it to a variable. |
| _ (wildcard) | Matches any value without binding it. |
| Range (1..=5) | Matches values within the range (only inclusive ranges are allowed). |
| | (OR) | Matches if any of the listed patterns match. |
| Tuple ((x, y)) | Destructures a tuple and binds its elements. |
| Struct (Point { x, y }) | Destructures a struct's fields. |
| Enum variant (Some(x), None) | Matches an enum variant and extracts its inner value. |
| Guard (pattern if condition) | Evaluates an additional condition after a pattern matches. |
| @ binding (x @ 1..=5) | Matches a pattern while also binding the value to a variable. |
| .. (ignore rest) | Ignores the remaining fields of a struct or tuple. |
Sample Code
#[derive(Debug)]
enum Coin {
Penny,
Nickel,
Dime,
Quarter(String), // A variant that holds a state name.
}
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn coin_value(coin: Coin) -> u32 {
match coin {
Coin::Penny => {
println!("Lucky penny!");
1
}
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State: {}", state);
25
}
}
}
fn main() {
// Match on an enum.
println!("--- Coin match ---");
println!("Penny: {} cents", coin_value(Coin::Penny));
println!("Quarter: {} cents", coin_value(Coin::Quarter("Alaska".to_string())));
// Range pattern on an integer.
println!("\n--- Integer range ---");
let n = 7;
match n {
1 => println!("one"),
2 | 3 | 5 | 7 | 11 => println!("prime"),
x @ 13..=19 => println!("teen: {}", x),
_ => println!("other"),
}
// Destructuring a tuple.
println!("\n--- Tuple pattern ---");
let point = (0, -2);
match point {
(0, 0) => println!("origin"),
(x, 0) | (0, x) => println!("on axis: {}", x),
(x, y) if x == y => println!("on diagonal: ({}, {})", x, y),
(x, y) => println!("general point: ({}, {})", x, y),
}
// Destructuring a struct.
println!("\n--- Struct pattern ---");
let p = Point { x: 3, y: 0 };
match p {
Point { x, y: 0 } => println!("on x-axis: x={}", x),
Point { x: 0, y } => println!("on y-axis: y={}", y),
Point { x, y } => println!("general point: ({}, {})", x, y),
}
// Pattern matching on Option.
println!("\n--- Option ---");
let opt: Option<i32> = Some(42);
match opt {
Some(x) if x > 0 => println!("positive: {}", x),
Some(x) => println!("non-positive: {}", x),
None => println!("no value"),
}
}
Notes
match is one of Rust's core features. The compiler checks exhaustiveness — if you add a new enum variant, any unhandled cases are caught at compile time.
For simple Option or Result matching, if let or while let can be more concise than a full match.
Each match arm (pattern => expr) is separated by a comma. When using a block ({ }), the trailing comma can be omitted.
For basic conditional branching, see 'if / else / if let'.
If you find any errors or copyright issues, please contact us.