Skip to content

Quick Ref: Pattern Matching ​

Updated Mar 2026

Pattern Matching Overview ​

match Expression ​

rust
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

fn value_in_cents(coin: &Coin) -> u32 {
    match coin {
        Coin::Penny => {
            println!("Lucky penny!");
            1
        }
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("State quarter: {:?}", state);
            25
        }
    }
}

Pattern Types ​

Literals and Variables ​

rust
let x = 1;
match x {
    1 => println!("one"),
    2 => println!("two"),
    3 => println!("three"),
    other => println!("something else: {other}"),  // Binds to variable
}

Wildcard and Rest ​

rust
match x {
    1 => println!("one"),
    _ => println!("anything"),  // Wildcard — ignores value
}

// Ignore parts with _
let (first, _, third) = (1, 2, 3);

// Ignore remaining with ..
struct Point { x: i32, y: i32, z: i32 }
let point = Point { x: 1, y: 2, z: 3 };
let Point { x, .. } = point;  // Only bind x

Ranges ​

rust
let x = 5;
match x {
    1..=5 => println!("one through five"),
    6..=10 => println!("six through ten"),
    _ => println!("something else"),
}

let ch = 'c';
match ch {
    'a'..='j' => println!("early letter"),
    'k'..='z' => println!("late letter"),
    _ => println!("not a letter"),
}

Or Patterns ​

rust
let x = 3;
match x {
    1 | 2 => println!("one or two"),
    3 | 4 => println!("three or four"),
    _ => println!("other"),
}

Destructuring ​

rust
// Structs
struct Point { x: i32, y: i32 }
let p = Point { x: 0, y: 7 };
match p {
    Point { x: 0, y } => println!("On y-axis at {y}"),
    Point { x, y: 0 } => println!("On x-axis at {x}"),
    Point { x, y } => println!("({x}, {y})"),
}

// Enums
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    Color(i32, i32, i32),
}

match msg {
    Message::Quit => println!("quit"),
    Message::Move { x, y } => println!("move to ({x}, {y})"),
    Message::Write(text) => println!("write: {text}"),
    Message::Color(r, g, b) => println!("color: ({r}, {g}, {b})"),
}

// Nested
enum Shape {
    Circle { center: Point, radius: f64 },
    Rectangle { top_left: Point, bottom_right: Point },
}

match shape {
    Shape::Circle { center: Point { x: 0, y: 0 }, radius } => {
        println!("Circle at origin with radius {radius}");
    }
    Shape::Circle { center, radius } => {
        println!("Circle at ({}, {}) r={radius}", center.x, center.y);
    }
    _ => {}
}

Guards ​

rust
let num = Some(4);
match num {
    Some(x) if x < 5 => println!("less than five: {x}"),
    Some(x) if x % 2 == 0 => println!("even: {x}"),
    Some(x) => println!("other: {x}"),
    None => println!("nothing"),
}

@ Bindings ​

rust
match msg {
    Message::Hello { id: id_variable @ 3..=7 } => {
        // id_variable is bound to the matched value
        println!("Found id in range: {id_variable}");
    }
    Message::Hello { id: 10..=12 } => {
        // Can test range but can't use the value
        println!("Found id in 10-12 range");
    }
    Message::Hello { id } => {
        println!("Other id: {id}");
    }
}

if let ​

rust
let config_max = Some(3u8);

// Instead of match with one useful arm:
if let Some(max) = config_max {
    println!("Max: {max}");
}

// With else
if let Some(max) = config_max {
    println!("Max: {max}");
} else {
    println!("No max configured");
}

// Chaining
if let Some(x) = option1 {
    // use x
} else if let Ok(y) = result1 {
    // use y
} else {
    // fallback
}

while let ​

rust
let mut stack = vec![1, 2, 3];

// Loop while pattern matches
while let Some(top) = stack.pop() {
    println!("{top}");
}
// Prints: 3, 2, 1

let else ​

rust
fn process(value: Option<i32>) -> i32 {
    // Bind or diverge (return/break/panic)
    let Some(x) = value else {
        return -1;
    };

    x * 2
}

fn parse_or_exit(s: &str) -> i32 {
    let Ok(n) = s.parse::<i32>() else {
        panic!("Failed to parse: {s}");
    };
    n
}

Pattern in for Loops ​

rust
let v = vec!['a', 'b', 'c'];

// Destructure enumerate tuple
for (index, value) in v.iter().enumerate() {
    println!("{index}: {value}");
}

// Destructure tuple elements
let pairs = vec![(1, 'a'), (2, 'b'), (3, 'c')];
for (num, letter) in &pairs {
    println!("{num} = {letter}");
}

Refutability ​

ContextAccepts
let bindingIrrefutable only
for loopIrrefutable only
Function parametersIrrefutable only
if letRefutable
while letRefutable
match armRefutable (except last with _)
let elseRefutable (must diverge in else)

Built with VitePress | Rust SOP Documentation