A pattern matches values against a shape, and can bind parts of the value to names.
Patterns are used in let statements, function and closure parameters,
match, if let, while let and for
(Reference: Patterns).
Grammar
Pattern:
|? PatternNoTopAlt ( | PatternNoTopAlt )*
PatternNoTopAlt:
PatternWithoutModernRange | ModernRangePattern
PatternWithoutModernRange:
LiteralPattern | IdentifierPattern | WildcardPattern | RestPattern
| ReferencePattern | StructPattern | TupleStructPattern | TuplePattern
| GroupedPattern | SlicePattern | PathPattern | MacroInvocation
| ObsoleteRangePattern
| Pattern | Example | Refutable? |
|---|---|---|
| Literal | 3, -1, "yes" | Always refutable |
| Identifier | x, mut x, ref x, n @ 1..=5 | Only through its @ subpattern |
| Wildcard | _ | Never |
| Rest | .. | Never |
| Range | 1..=5, 'a'..='z' | Unless it covers the whole type |
| Reference | &x, &mut x | Through its subpattern |
| Struct | Point { x, y: 0 } | For a multi-variant enum, or through a subpattern |
| Tuple struct | Some(x) | The same |
| Tuple | (a, b) | Through a subpattern |
| Grouped | (pat) | Through its subpattern |
| Slice | [a, .., b] | See below |
| Path | Colour::Red, MAX | For a multi-variant enum or a refutable constant |
| Or-pattern | A | B | Unless the alternatives together cover every value |
| Macro invocation | my_pat!() | Depends on the expansion |
Refutability
An irrefutable pattern always matches, like (x, y) against
(1, 2). A refutable pattern may fail, like (a, 3)
against (1, 2). Refutable patterns may appear only where the failure can
be handled: match, if let, while let and
let else. let without else, parameters and
for need irrefutable patterns.
Literal patterns
LiteralPattern: -? LiteralExpression
A literal pattern matches exactly the value of the literal, optionally negated. C
string literals are accepted by the grammar, but matching on &CStr is
a type error, because it does not have structural equality.
Identifier patterns
IdentifierPattern: ref? mut? IDENTIFIER ( @ PatternNoTopAlt )?
An identifier pattern binds the matched value to a new variable. The name must be
unique within the pattern, and the new binding shadows other variables of the same
name. By default the value is copied if its type is Copy, and otherwise
moved.
| Form | Meaning |
|---|---|
x | Binds by value (move or copy) |
mut x | Binds by value; the variable is mutable |
ref x | Binds a shared reference to the matched place |
ref mut x | Binds a mutable reference to the matched place |
x @ subpattern | Binds the whole value while also testing the subpattern |
match n {
e @ 1..=5 => println!("got {e}"),
_ => {}
}
let Person { name, ref age } = person; // moves name, borrows age: a partial move
A single identifier that names a constant, a unit struct or a unit variant in scope is
a path pattern, not a new binding. Path patterns take
precedence, so a typo in a variant’s name can bind instead of match, and
ref or ref mut on an identifier that names a constant is an
error.
Binding modes
Patterns are matched from the top down. The default binding mode starts as
move. When a reference is matched by a non-reference pattern, it is
automatically dereferenced and the mode changes: through & it becomes
ref; through &mut it becomes ref mut
unless it is already ref. Non-reference patterns are all patterns
except bindings, wildcards, reference patterns and const patterns of
reference type.
let x: &Option<i32> = &Some(3);
if let Some(y) = x { // y has type &i32, not i32
println!("{y}");
}
let mut pair = (1, 2);
let (a, b) = &mut pair; // a and b have type &mut i32
*a += 1;
Writing ref, ref mut, mut or a reference
pattern is allowed only while the default mode is move. These are
errors:
let [mut x] = &[()]; // error
let [ref x] = &[()]; // error
let [ref mut x] = &mut [()]; // error
let [&x] = &[&()]; // error
Before edition 2024,
these forms were accepted under a non-move default. An explicit mut
forced the mode back to move, and a reference pattern matched the scrutinee and reset
it to move.
Wildcard patterns
_ matches any value without copying, moving or borrowing it. Inside a
struct, tuple or tuple struct pattern it matches a single field. It always matches.
A let _ = expr; does not bind anything, so a place expression on the
right is not moved.
Rest patterns
.. matches zero or more elements that are not otherwise matched. It is
allowed only in tuple, tuple struct and slice patterns, and at most once in each. In a
slice pattern it may be the subpattern of an identifier, as in
tail @ ... The form (..) matches a tuple of any size.
match tuple {
(1, .., y, z) => println!("y={y} z={z}"),
(.., 5) => println!("tail must be 5"),
(..) => println!("everything else"),
}
Range patterns
| Form | Matches |
|---|---|
a..=b | From a to b, inclusive |
a..b | From a up to but not including b |
a.. | All values from a up |
..b | All values below b |
..=b | All values up to and including b |
- A bound is a character, byte, integer or float literal, a
-before a number, or a path to a constant of achar, integer or float type. Both bounds must have the same type. - Ranges must be non-empty:
a..=brequiresa ≤ b,a..brequiresa < b, and..bmust not start at the type’s minimum. Float constants may not beNaN. - A range is irrefutable if it covers every value of a fixed-width integer or of
char, as0u8..=255u8does. - A half-open range in a slice pattern must be parenthesised:
[(1..), _]. - Before edition 2021,
...could be used instead of..=. It is invalid in edition 2021 and later.
Reference patterns
ReferencePattern: ( & | && ) mut? PatternWithoutModernRange
A reference pattern dereferences the matched reference and matches the rest against
the result. && is one token and matches a reference to a
reference. &mut matches a mutable reference; the mutability must
match. &0..=5 is not allowed; write &(0..=5).
Struct patterns
A struct pattern lists fields by name, by tuple index, or as a shorthand binding, and
ends with .. to ignore the rest. Without .., all fields must
be listed. Field order does not matter. A struct pattern on a union must name exactly
one field.
match p {
Point { x: 10, y: 20 } => (),
Point { y: 10, x: 20 } => (), // order does not matter
Point { x: 10, .. } => (),
Point { x, y } => println!("{x} {y}"),
}
Tuple struct patterns
Written Path(item, item), for tuple structs and tuple variants. Items are
patterns and may include ... Tuple struct patterns are resolved in the
value namespace, and struct patterns in the type namespace.
Tuple patterns
Written (a, b). A one-element tuple pattern needs a trailing comma,
(x,), to distinguish it from a grouped pattern.
Grouped patterns
Parentheses control precedence: &(0..=5), or
x @ (A | B).
Slice patterns
[…] matches arrays of known size and slices of dynamic size. A pattern on
an array is irrefutable if every element pattern is. A pattern on a slice is
irrefutable only when it is a single .. or name @ .. as its
sole element, so other slice patterns need a wildcard arm.
match v[..] {
[a, b] => { /* length 2 */ }
[a, b, c] => { /* length 3 */ }
[first, .., last] => println!("{first} {last}"),
[] | [_] => { /* length 0 or 1 */ }
}
Path patterns
A path pattern names a constant, or a struct or enum variant with no fields. An
unqualified path can refer to variants, structs, constants and associated constants. A
qualified path, like <T as Trait>::CONST, can refer only to associated
constants.
Constant patterns
A constant C of type T can be used as a pattern if
T: PartialEq and the value of C has structural
equality, defined recursively:
- Integers,
str,boolandcharalways have it. - Tuples, arrays and slices have it if all their elements do.
- References have it if their target does.
- Structs and enums have it if
PartialEqis derived and all fields (of the active variant, for an enum) have it. - Raw pointers have it only if defined as a constant integer and then cast or transmuted.
- Floats have it if they are not
NaN. - Nothing else has it.
The value must be known before monomorphisation, so associated constants that depend
on generic parameters cannot be used. It may not refer to mutable statics, statics
with interior mutability or extern statics.
Or-patterns
p | q matches if any alternative matches, trying them left to right.
Or-patterns can nest, and are allowed wherever Pattern is accepted. They
are not allowed at the top level of a let binding or a function or closure
parameter, which use PatternNoTopAlt; parentheses are needed there:
let (A | B) = v;.
p | q is ill-formed if the two alternatives have types that do not unify,
do not bind the same names, or bind a name with different types or binding modes.
Or-patterns have the lowest precedence among unparenthesised patterns, so
x @ A(..) | B(..) is an error, as x is not bound in the
second alternative.