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:letstatements- Function and closure parameters
forloops
-
Refutable Patterns: These patterns might fail to match a given value for a specific type. Examples include matching a literal (
42only matches the value 42), an enum variant (Some(x)doesn’t matchNone), or a range (1..=5doesn’t match 6). Refutable patterns are used in contexts designed to handle potential match failures:matchexpression arms (except potentially the final wildcard_arm)if letconditionswhile letconditionslet elsestatements
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.