21.3 Refutable vs. Irrefutable Patterns
A crucial concept is the distinction between refutable and irrefutable patterns:
-
Irrefutable Patterns: These patterns are guaranteed to match any value of the expected type. Examples include binding a variable (
let x = value;
), destructuring a struct (let MyStruct { field1, field2 } = s;
), or a tuple (let (a, b) = tuple;
). Irrefutable patterns are required in contexts where a match failure is not meaningful or allowed, such as:let
statements- Function and closure parameters
for
loops
-
Refutable Patterns: These patterns might fail to match a given value for a specific type. Examples include matching a literal (
42
only matches the value 42), an enum variant (Some(x)
doesn’t matchNone
), or a range (1..=5
doesn’t match 6). Refutable patterns are used in contexts designed to handle potential match failures:match
expression arms (except potentially the final wildcard_
arm)if let
conditionswhile let
conditionslet else
statements
The compiler enforces this distinction. Trying to use a refutable pattern where an irrefutable one is needed (e.g., let Some(x) = option_value;
) results in a compile-time error because the code wouldn’t know what to do if option_value
were None
.