Advanced match in Rust
| Match nested shapes | |
| Match ranges | |
| Bind with @ | |
| Match references |
Match nested shapes
Patterns can look several layers deep in one arm. Nest enum names inside each other and bind the inner numbers directly, so one arm describes the whole shape.
A wildcard arm at the end catches every shape the earlier arms skip.
enum Shape { Dot, Line(i32, i32) }
enum Pic { Empty, One(Shape) }
fn main() {
let p = Pic::One(Shape::Line(1, 2));
match p {
Pic::One(Shape::Line(x, y)) => println!("line"),
_ => println!("other"),
}
}
The first arm only fires for a picture holding a line and binds both endpoints. Every other picture falls to the wildcard arm below it.
Match ranges
A range arm groups many numbers into one branch. Two dots with an equals sign form an inclusive range, so low, middle, and high each get one arm.
Order arms from narrow to wide and keep a wildcard last for values outside every range.
fn main() {
let n = 7;
match n {
0..=4 => println!("low"),
5..=9 => println!("mid"),
_ => println!("high"),
}
}
The number 7 lands in the middle range. Ranges keep the match short where a chain of single value arms would grow long.
Bind with @
The at sign binds the whole matched value while also checking a pattern. Place a name, then at, then the pattern, and the name holds the value for the arm body.
This fits ranges and listed variants when the exact number matters inside the arm as well as the branch choice.
fn main() {
let n = 7;
match n {
v @ 5..=9 => println!("mid"),
_ => println!("other"),
}
}
Here v captures the matched number while the range checks its band. The arm body can then use v for math, logging, or building the next value.
Match references
Matching a reference borrows instead of moving. Match on a borrowed value and the bound names become borrows too, which keeps the original usable after the match.
This pattern appears with Option and other owned values that must stay alive for later code.
fn main() {
let x = Some(5);
match &x {
Some(v) => println!("five"),
None => println!("none"),
}
}
The match borrows x, so x remains valid below the match. Match ergonomics turn v into a borrow automatically with no extra syntax.
Next: Option combinators
Article author: Arthur Isaev