Skip to main content

Pattern Syntax in Rust

Created: October 29, 2025 4 min read
Table of Contents

Patterns are one of Rust’s most powerful features, providing a way to express complex logic for matching and destructuring data. They are used in match statements, if let expressions, let bindings, and function parameters. This guide serves as a reference to the various syntaxes you can use to construct patterns.

1. Matching Literals

The simplest pattern is a literal value. This allows you to match against fixed values like numbers, characters, and string literals.

fn match_literal(x: i32) {
    match x {
        1 => println!("one"),
        2 => println!("two"),
        _ => println!("something else"),
    }
}
```
### 2. Matching Named Variables

A pattern that consists of a variable name will match any value, binding that value to the variable name for use in the match arm's expression.

````rust
let x = Some(5);
let y = 10;

match x {
    Some(50) => println!("Got 50"),
    // `y` here is a new variable that shadows the outer `y`. It will match any value inside `Some`.
    Some(y) => println!("Matched, y = {:?}", y),
    _ => println!("Default case, x = {:?}", x),
}

println!("at the end: x = {:?}, y = {:?}", x, y); // Outer y is still 10.
```
### 3. Multiple Patterns with `|`

You can match against multiple patterns in a single arm using the `|` (or) operator.

````rust
let x = 1;

match x {
    1 | 2 => println!("one or two"),
    3 => println!("three"),
    _ => println!("anything"),
}
```
### 4. Matching Ranges with `..=`

You can match against an inclusive range of values using the `..=` syntax. This is only allowed for `char` and numeric values.

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

let c = 'c';
match c {
    'a'..='j' => println!("early letter"),
    'k'..='z' => println!("late letter"),
    _ => println!("something else"),
}
```
### 5. Destructuring

Patterns can be used to dismantle structs, enums, tuples, and references to access their inner values.

#### Destructuring Structs

````rust
struct Point {
    x: i32,
    y: i32,
}

let p = Point { x: 0, y: 7 };

// Destructure and rename variables
let Point { x: a, y: b } = p;
println!("a = {}, b = {}", a, b);

// Destructure with shorthand
match p {
    Point { x, y: 0 } => println!("On the x axis at {}", x),
    Point { x: 0, y } => println!("On the y axis at {}", y),
    Point { x, y } => println!("On neither axis: ({}, {})", x, y),
}
```
#### Destructuring Enums

````rust
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
}

let msg = Message::Move { x: 3, y: 4 };

match msg {
    Message::Quit => println!("Quit"),
    Message::Move { x, y } => println!("Move to ({}, {})", x, y),
    Message::Write(s) => println!("Write: {}", s),
}
```
### 6. Ignoring Values in a Pattern

Sometimes you need to ignore parts of a value.

- `_` ignores a single value.
- `..` ignores all remaining values in a struct, tuple, or slice.

````rust
// Ignoring with _
let numbers = (2, 4, 8, 16, 32);
match numbers {
    (first, _, third, _, fifth) => {
        println!("Some numbers: {}, {}, {}", first, third, fifth);
    }
}

// Ignoring with ..
struct Point3D { x: i32, y: i32, z: i32 }
let point = Point3D { x: 10, y: 5, z: -2 };
match point {
    Point3D { x, .. } => println!("x is {}", x),
}

match numbers {
    (first, .., last) => {
        println!("The first number is {} and the last is {}", first, last);
    }
}
```
### 7. Match Guards with `if`

A match guard is an additional `if` condition that can be placed after a pattern in a `match` arm. This allows for more complex filtering.

````rust
let num = Some(4);

match num {
    Some(x) if x % 2 == 0 => println!("The number {} is even", x),
    Some(x) => println!("The number {} is odd", x),
    None => (),
}
```
### 8. `@` Bindings

The `@` operator lets you create a variable that holds a value while simultaneously testing that value against a pattern.

````rust
enum Message {
    Hello { id: i32 },
}

let msg = Message::Hello { id: 5 };

match msg {
    Message::Hello {
        // Bind the value of `id` to `id_variable` while also testing
        // that it falls within the range 3..=7.
        id: id_variable @ 3..=7,
    } => {
        println!("Found an id in range: {}", id_variable);
    }
    Message::Hello { id: 10..=12 } => {
        println!("Found an id in another range");
    }
    Message::Hello { id } => {
        println!("Found some other id: {}", id);
    }
}
```

By combining these syntactical elements, you can create highly expressive and safe patterns to control your program's logic.

## Resources

- [Official Documentation](https://docs.python.org/3/)
- [Language Specification](https://docs.python.org/3/reference/)
- [Community Resources](https://www.python.org/community/)

Comments

Share this article

Scan to read on mobile