21.2 Overview of Pattern Syntax

Patterns in Rust combine several building blocks:

  • Literals: Match exact constant values (e.g., 42, -1, 3.14, true, 'a', "hello"). Note: Floating-point matching requires specific language features due to equality complexities.
  • Identifiers (Variables): Match any value and bind it to a variable name (e.g., x). If the identifier names a constant, it matches that constant’s value instead of binding.
  • Wildcard (_): Matches any value without binding it. Used to ignore parts or all of a value.
  • Ranges (start..=end): Matches any value within an inclusive range (e.g., 0..=9, 'a'..='z'). Primarily used for char and integer types. Exclusive ranges (..) are not allowed in patterns.
  • Tuple Patterns: Destructure tuples by position (e.g., (x, 0, _), (.., last)).
  • Struct Patterns: Destructure structs by field names (e.g., Point { x, y }, Config { port: 80, .. }). Supports field name punning (x is shorthand for x: x).
  • Enum Patterns: Match specific enum variants, optionally destructuring associated data (e.g., Option::Some(val), Result::Ok(data), Color::Rgb { r, g, b }).
  • Slice & Array Patterns: Match fixed-size arrays or variable-size slices based on elements (e.g., [first, second], [head, ..], [.., last], [a, b, rest @ ..]).
  • Reference Patterns (&, &mut): Match values behind references.
  • ref and ref mut Keywords: Create references to parts of a value being matched, avoiding moves.
  • OR Patterns (|): Combine multiple patterns; if any sub-pattern matches, the arm executes (e.g., ErrorKind::NotFound | ErrorKind::PermissionDenied => ...).
  • @ Bindings (name @ pattern): Bind the entire value matched by a sub-pattern to a variable while also testing against that sub-pattern (e.g., id @ 1..=9).