A pattern describes a value shape and the names to bind from it. The same pattern language appears in bindings, loops, conditional patterns, and match arms.
Wildcards
_ matches any value without creating a binding.
for _ in 0..3 {
retry()
}Use a wildcard when a value is intentionally ignored or when it completes an otherwise open-ended match.
Bindings
A fresh identifier matches any value and binds that value to the name.
match result {
Some(value) => consume(value)
None => use_default()
}Whether an identifier is a new binding or a visible constant is resolved by the compiler. Constants in pattern position match their folded value.
Literals
Boolean, numeric, character, and string literals match equal values.
match command {
"start" => start()
"stop" => stop()
_ => unknown()
}Floating-point patterns should be avoided where rounding makes exact equality an unstable domain rule.
Tuples
Tuple patterns match arity and destructure positions.
(host, port) := endpointThe outer parentheses may be omitted in binding and iteration positions where the comma is unambiguous.
for key, value in entries {
store(key, value)
}Structs
Struct patterns name the fields to inspect.
Point { x, y } := pointRename a field by supplying a subpattern.
User { id: user_id, name } := user.. ignores fields that are not explicitly listed.
Request { method, path, .. } := requestAnonymous record patterns are structural; nominal struct patterns also check the owning type.
Variants
Enum, Option, Result, and declared error variants use constructor-shaped
patterns.
match result {
Ok(value) => consume(value)
Err(error) => report(error)
}Tuple-style variants bind positional payloads. Struct-style variants bind named fields. Unit variants have no payload.
Qualify a variant when a bare name is ambiguous.
match state {
NetworkState.Ready => connect()
StorageState.Ready => load()
}The checker uses the subject’s expected type to resolve unambiguous bare variants.
Slices
Slice patterns match sequence elements.
match values {
[] => empty()
[only] => one(only)
[head, ..tail] => many(head, tail)
}A rest pattern absorbs the remaining elements. The current parser supports a
bare .. and a named rest binding.
Ranges
Inclusive and exclusive range patterns match values inside their endpoints.
match digit {
0..=9 => decimal()
_ => invalid()
}Range endpoints must be valid compile-time pattern values of a compatible ordered type.
Bound patterns
name @ subpattern binds the whole matched value while also requiring the
subpattern.
match value {
digit @ 0..=9 => use_digit(digit)
_ => reject()
}This avoids reconstructing a value from its parts merely to retain the original.
Alternatives
left | right matches either alternative.
match event {
Created(id) | Updated(id) => refresh(id)
Deleted(id) => remove(id)
}Every alternative must bind the same names with compatible types. Otherwise the arm body would not have a consistent environment.
Refutability
An irrefutable pattern is guaranteed to match its input type, such as a plain binding or complete tuple destructure. A refutable pattern can fail, such as a variant, literal, range, or constrained slice.
Use refutable patterns only where failure has defined control flow:
- an
ifpattern condition; - a
for pattern := expressionloop; - a
matcharm; - a binding followed by a diverging
else.