Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The match expression is a control flow construct in Rust that compares a value against a series of patterns and executes the code associated with the first matching pattern. Because it is an expression rather than a statement, it evaluates to a value that can be assigned, returned, or passed to other functions.
match target_expression {
    pattern_1 => expression_1,
    pattern_2 | pattern_3 => expression_2,
    pattern_4 if condition => expression_3,
    _ => fallback_expression,
}

Core Mechanics

Exhaustiveness Rust enforces exhaustive pattern matching at compile time. Every possible valid value of the target_expression’s type must be explicitly handled by a pattern. If the type has a vast or infinite state space (such as i32 or String), a catch-all pattern must be provided to satisfy the compiler. Type Uniformity Because match evaluates to a single value, the expressions in every match arm must resolve to the exact same type. If one arm evaluates to an i32, all other arms must also evaluate to an i32. If the match is used purely for side effects, all arms must evaluate to the unit type (). Sequential Evaluation Patterns are evaluated strictly from top to bottom. The compiler executes the expression of the first pattern that matches the target value. Once a match is found, the expression short-circuits, and subsequent arms are ignored.

Pattern Syntax and Capabilities

The left side of a match arm (the pattern) supports several structural mechanics:
  • Literals: Matching exact values (e.g., 1, "text").
  • Multiple Patterns: The | operator allows a single arm to match multiple distinct patterns.
  • Ranges: The ..= syntax matches an inclusive range of scalar values (e.g., 1..=5).
  • Destructuring: Patterns can unpack compound data types—such as tuples, arrays, structs, and enums—binding their inner values to local variables.
  • Wildcards: The _ (underscore) pattern matches any value without binding it to a variable, effectively acting as a default or ignore mechanism.
  • Match Guards: An if condition appended to a pattern. The arm is only executed if the pattern matches and the guard evaluates to true.

Abstract Syntax Example

The following example demonstrates destructuring, ranges, match guards, and exhaustiveness without relying on a specific implementation scenario:
let target = Some((4, 10));

let result: i32 = match target {
    // Destructures the tuple; executes only if the guard condition is met
    Some((x, y)) if x == y => x + y,
    
    // Matches if the first tuple element is within the inclusive range 1 to 5
    Some((1..=5, y)) => y,
    
    // Uses a wildcard to ignore the first element, binding only the second
    Some((_, y)) => y * 2,
    
    // Exhausts the remaining Option variant
    None => 0,
};

Variable Binding and Shadowing

When a variable name is used as a pattern, it acts as an irrefutable catch-all that binds the matched value to that variable name. This introduces a new lexical scope for the right side of the match arm. If the variable name matches a variable in the outer scope, it will shadow the outer variable.
let x = 5;
let y = 10;

match x {
    // 'y' here is a new binding, not a comparison to the outer 'y'.
    // It matches any value and shadows the outer 'y' of 10.
    y => println!("Matched: {}", y), 
}
To compare against an existing variable rather than shadowing it, match guards must be used:
let x = 5;
let y = 10;

match x {
    // 'val' binds the target, and the guard compares it to the outer 'y'
    val if val == y => println!("Matches outer y"),
    _ => println!("Does not match"),
}
Master Rust with Deep Grasping Methodology!Learn More