In Rust, one of the core features that distinguishes it from many other languages is its powerful system for pattern matching. Pattern matching provides a way to access the data in data structures, and it’s a tool that allows for concise and expressive code. In this article, we’ll dive deep into pattern matching in Rust to understand its strengths and intricacies.
What is Pattern Matching?
Pattern matching allows you to compare a value against a pattern and, if they match, to destructure or extract parts of that value. It’s like a Swiss army knife for Rustaceans; whether you’re working with option types, results, enums, or destructuring complex data types, pattern matching comes to the rescue.
Basic Pattern Matching with match
The match keyword is the heart of pattern matching in Rust. It allows you to compare a value to multiple patterns and execute code based on the first pattern that matches.
let x = Some(5);
match x {
Some(5) => println!("It's a five!"),
Some(_) => println!("It's something, but not a five."),
None => println!("It's nothing."),
}
Here, x matches the first arm, so "It's a five!" is printed.
Destructuring
Pattern matching shines when you’re dealing with complex data types. For instance, when you’re working with structs or enums, you can use patterns to extract values.
struct Point {
x: i32,
y: i32,
}
let p = Point { x: 1, y: 2 };
match p {
Point { x, y: 2 } => println!("x is {} and y is 2", x),
Point { x: 0, y } => println!("x is 0 and y is {}", y),
_ => println!("Other case"),
}
Using _ as a Wildcard
In patterns, the _ symbol can be used as a wildcard, meaning it will match any value but not bind it to a name.
let x = 3;
match x {
1 => println!("One"),
2 => println!("Two"),
_ => println!("Other"),
}
Using if in Match Arms
Rust allows for even finer control with pattern matching by allowing conditions in match arms with the if keyword.
let pair = (2, -2);
match pair {
(x, y) if x == y => println!("These are twins"),
(x, y) if x + y == 0 => println!("Antimatter, kaboom!"),
(x, _) if x % 2 == 1 => println!("The first one is odd"),
_ => println!("No correlation..."),
}
Matching on Enums
Rust’s enums are versatile, and when combined with pattern matching, they become even more powerful.
enum Result<T, E> {
Ok(T),
Err(E),
}
let res: Result<i32, &str> = Result::Ok(42);
match res {
Result::Ok(value) => println!("Success: {}", value),
Result::Err(err) => println!("Error: {}", err),
}
Advanced Pattern Matching
Beyond the basics, Rust’s pattern matching offers more advanced constructs to refine and condense our code further.
Nested Patterns
Patterns can be nested to match inner values of complex data types.
enum Color {
RGB(u8, u8, u8),
HSV(u32, u8, u8),
}
let color = Color::RGB(255, 0, 0);
match color {
Color::RGB(255, green, blue) if green == 0 && blue == 0 => println!("This is red!"),
Color::RGB(..) => println!("Some RGB color"),
_ => println!("Some other color"),
}
At Bindings
The @ operator allows you to test a value against a pattern and bind the value to a variable.
let some_value = 5;
match some_value {
x @ 1..=5 => println!("Value is in the range 1-5 and is: {}", x),
_ => println!("Value is out of range"),
}
Multiple Patterns
Using the operator, you can match against various patterns, allowing for cleaner code in cases where multiple patterns lead to the same result.
let character = 'a';
match character {
'a' | 'e' | 'i' | 'o' | 'u' => println!("Vowel"),
_ => println!("Consonant or not a letter"),
}
Match Guards
These were briefly introduced before, but it’s worth noting that match guards (conditions after the if keyword) offer additional flexibility when patterns alone aren't enough.
let pair = (5, -5);
match pair {
(x, y) if x + y == 0 => println!("Sum is zero"),
_ => println!("Sum isn't zero"),
}
Refutable and Irrefutable Patterns
Patterns come in two flavours:
- Irrefutable Patterns: These are patterns that will always match. For example, when you use
let x = 5;,xis an irrefutable pattern. - Refutable Patterns: These can fail to match. For example,
Some(x)is refutable because a value can also beNone.


