100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Rust

match Expressions in Rust

Master Rust's exhaustive match expression for pattern matching on values, enums, tuples, and ranges.

Control FlowIntermediate9 min readJul 8, 2026
Analogies

Introduction

match is Rust's powerful pattern-matching control flow construct. It compares a value against a series of patterns and executes the code associated with the first matching pattern. Unlike switch statements in many other languages, match in Rust is exhaustive: the compiler requires every possible value of the matched type to be covered, either explicitly or through a catch-all _ pattern, which eliminates an entire class of bugs from forgotten cases.

🏏

Cricket analogy: match is like an umpire checking a dismissal against every possible mode — bowled, caught, lbw, run-out — and Rust's compiler insists every mode be covered (or a catch-all "_") before the decision is accepted, unlike a casual switch-style scorecard that might silently miss a rare dismissal type.

Syntax

rust
match value {
    pattern1 => expression1,
    pattern2 => expression2,
    _ => default_expression,
}

// as an expression producing a value
let result = match value {
    pattern1 => expr1,
    _ => expr2,
};

Explanation

Each arm of a match consists of a pattern and an expression separated by =>, with arms separated by commas. match can match literal values, ranges (like 1..=5), tuples, and enum variants, and it can destructure structs and enums to bind their inner fields to new variables within the arm. Because match is itself an expression, it can return a value, and just like if-else, all arms must evaluate to the same type when used this way. The exhaustiveness check is performed at compile time — if you match on an enum and add a new variant later without updating the match, compilation fails until you handle the new case.

🏏

Cricket analogy: Each match arm pairs a dismissal pattern with an outcome via =>, like matching literal scores, run ranges (1..=5), or destructuring a Wicket enum variant to bind the bowler's name; since match is an expression, every arm must return the same result-type, and adding a new dismissal variant later (like "obstructing the field") breaks compilation until every match handles it.

Example

rust
enum Shape {
    Circle(f64),
    Rectangle(f64, f64),
    Triangle { base: f64, height: f64 },
}

fn area(shape: &Shape) -> f64 {
    match shape {
        Shape::Circle(radius) => std::f64::consts::PI * radius * radius,
        Shape::Rectangle(w, h) => w * h,
        Shape::Triangle { base, height } => 0.5 * base * height,
    }
}

fn main() {
    let n = 7;
    let description = match n {
        0 => "zero",
        1..=5 => "small",
        6..=10 => "medium",
        _ => "large",
    };
    println!("{} is {}", n, description);

    let c = Shape::Circle(2.0);
    println!("area = {:.2}", area(&c));
}

Output

text
7 is medium
area = 12.57

Key Takeaways

  • match is exhaustive — the compiler forces you to cover every possible case or use a _ wildcard.
  • Arms use the pattern => expression, syntax and can bind variables from the matched value.
  • match can match literals, ranges, tuples, and enum variants, including destructuring.
  • match is an expression and can produce a value, with all arms needing the same type.
  • Adding a new enum variant later causes a compile error at every non-exhaustive match on it, aiding refactoring safety.

Practice what you learned

Was this page helpful?

Topics covered

#Rust#RustProgrammingStudyNotes#Programming#MatchExpressionsInRust#Match#Expressions#Syntax#Explanation#StudyNotes#SkillVeris