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.

An identifier pattern binds a matched value to a local variable. It consists of a variable name (the identifier), optional ref and/or mut modifiers to alter the binding mode, and an optional @ operator to bind the identifier while simultaneously matching the value against a subpattern. When evaluated, an identifier pattern unconditionally matches the value (unless constrained by a refutable subpattern) and introduces a new variable into the current lexical scope.

Syntax

IdentifierPattern :
    ref? mut? IDENTIFIER ( @ Pattern )?

Components and Explicit Binding Modes

The behavior of the identifier pattern is dictated by its modifiers, which control how the value is bound to the identifier.
  • IDENTIFIER: The name of the variable. It must be a valid Rust identifier. The wildcard _ is not an identifier pattern; it is a distinct wildcard pattern that does not bind a variable.
  • mut: Alters the binding mode so that the newly bound variable is mutable. It does not change whether the value is moved, copied, or borrowed; it only affects the mutability of the resulting local variable.
  • ref: Alters the binding mode to bind the variable by reference rather than by value.
    • ref creates a shared reference (&T).
    • ref mut creates a mutable reference (&mut T).
  • @ (Subpattern Binding): The at-binding operator binds the value to the IDENTIFIER only if the value also successfully matches the subsequent Pattern. The refutability of the entire identifier pattern is determined entirely by this subpattern. If the subpattern is irrefutable, the @ pattern is also irrefutable and is valid in standard let statements or function parameters. If the subpattern is refutable, it must be used in refutable contexts like if let or match arms.

Match Ergonomics (Default Binding Modes)

If an identifier pattern does not explicitly use the ref or ref mut keywords, its binding mode is determined by the compiler’s default binding modes (Match Ergonomics). When a reference is matched against a structural pattern, the binding mode transitions to a reference mode. Any identifier pattern encountered while in a reference binding mode will automatically bind by reference:
  • If the context is a shared reference (&T), the identifier implicitly binds as ref (yielding &T).
  • If the context is a mutable reference (&mut T), the identifier implicitly binds as ref mut (yielding &mut T).

Syntax Visualization

Standard Value Binding Binds the value directly to the identifier.
let x = 10; 
Mutable Binding Binds the value to a mutable identifier.
let mut x = 10;
Explicit Reference Binding Binds the identifier as a reference to the matched value.
let ref x = 10;      // x is &i32
let ref mut y = 10;  // y is &mut i32
Implicit Reference Binding (Match Ergonomics) Binds the identifier by reference automatically when destructuring a borrowed scrutinee.
let opt = &Some(10);
if let Some(x) = opt {
    // The scrutinee is &Option<i32>.
    // `x` is an identifier pattern that implicitly binds as `ref x`.
    // The type of `x` is &i32.
}
Irrefutable Subpattern Binding (@) Binds the identifier to the value while evaluating an irrefutable subpattern. This is valid in standard let bindings.
let tuple @ (a, b) = (1, 2);
// `tuple` is bound to (1, 2).
// `a` is bound to 1, and `b` is bound to 2.
Refutable Subpattern Binding (@) Binds the identifier to the value while evaluating a refutable subpattern constraint. This requires a refutable context.
if let x @ 1..=10 = 5 {
    // `x` is bound to 5 because 5 matches the 1..=10 subpattern.
}
Combined Modifiers Modifiers and subpatterns can be combined within a single identifier pattern.
if let ref mut x @ Some(_) = Some(5) {
    // `x` is a mutable reference to the Option containing 5.
}

Shadowing and Scope

If the IDENTIFIER shares a name with a variable already present in the enclosing scope, the identifier pattern shadows the existing variable for the duration of the new scope. It does not mutate or reassign the outer variable.
Master Rust with Deep Grasping Methodology!Learn More