Advanced match in Rust

Contents
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

Related articles
Rust
Rust course: zero to hero in 50 lessons
What is Rust and where it runs
Install Rust
cargo new
Your first program
Variables
Numbers
Strings
Booleans
Tuples
Arrays
Vectors
Slices
if and else
match
Loops
Ownership
Borrowing
Lifetimes
Functions
Structs
Enums in Rust
Advanced match in Rust
Option combinators in Rust
Result and the question mark in Rust
Advanced strings in Rust
Vec methods in Rust
HashMaps in Rust
Modules in Rust
Crates and workspaces in Rust
Testing in Rust
Error handling
Traits
Generics
Trait bounds
Closures
Iterators
Smart pointers
Threads
Mutex and Arc
Files
CLI arguments
Environment variables
Diagnostics
Time
Parsing strings
TCP networking
Capstone: wordfreq CLI
Capstone: tiny HTTP server
Modern Rust tour
Hero roadmap: the whole course on one page
Install Rust on Windows 11
Install Rust on Ubuntu
Install Rust on Rocky Linux
Install Rust on macOS
Install Rust on FreeBSD
Rust in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: