Patterns
https://doc.rust-lang.org/reference/patterns.html
Patterns are pieces of syntax which are used to match values against different variants of a type and constants/literals, optionally destructuring and binding internal values to names.
We define two types of patterns in Rust:
- refutable
- irrefutable
Irrefutable patterns are such patterns that are always true. We can use the let binding to demonstrate these:
#![allow(unused)] fn main() { // bind to identifier - works for any value of any type let my_bidning = 33; // destructuring a tuple let (first, second) = (33, 33); // the unit type has only one value, the unit itself let () = (); // similar case with a unit struct struct Empty; let Empty = Empty; // destructuring a structure struct Point { x: isize, y: isize, } // x and y are now defined bindings let Point { x, y } = Point { x: 24, y: 23 }; // you can also rename let Point { x: other_x, y: other_y } = Point { x: 10, y: 11 }; // you can ignore some fields let Point { x: third_x, y: _ } = Point { x: 1, y: 2 }; // you can only take some fields and ignore the rest let Point { x: fourth_x, .. } = Point { x: 3, y: 4 }; }
Irrefutable patterns are also available in function parameters and every place where refutable patterns are valid.
Refutable patterns only match in some cases, either because you are matching a field against a constant, or because you are matching on a type that has multiple variants.
These patterns are only valid in the following three structures:
if-letwhile-letmatch
#![allow(unused)] fn main() { let result = Ok(5); let option = Some(5); if let Ok(5) = result { // only runs if result is Ok(5) } if let Ok(number) = result { // only runs if result is Ok and binds // the contained value to the identifier `number`. // You can use any valid identifier } if let Some(_) = option { // only runs if option is Some, // but ignores contained value // okay for other Enums, but for Option use methods .is_some(), is_none() // for Result use .is_ok(), .is_err() } struct Point { x: isize, y: isize, } let point = Point { x: 5, y: 5 }; if let Point { 5, y } = point { // only runs if x is 5, // binding the other field to the name y } }