Pattern Usage Contexts
match
Arms
match VALUE {
PATTERN => EXPRESSION,
PATTERN => EXPRESSION,
}
match
expressions must be exhaustive. Use _
as a catchall pattern:
match x {
None => None,
Some(i) => Some(i + 1),
}
Conditional if let
Expressions
More flexible than match
for single-pattern matching:
fn main() { let favorite_color: Option<&str> = None; let is_tuesday = false; let age: Result<u8, _> = "34".parse(); if let Some(color) = favorite_color { println!("Using your favorite color, {color}, as the background"); } else if is_tuesday { println!("Tuesday is green day!"); } else if let Ok(age) = age { if age > 30 { println!("Using purple as the background color"); } else { println!("Using orange as the background color"); } } else { println!("Using blue as the background color"); } }
if let
doesn’t check exhaustiveness, unlike match
. Can introduce shadowed variables within the conditional scope.
while let
Conditional Loops
fn main() { let (tx, rx) = std::sync::mpsc::channel(); std::thread::spawn(move || { for val in [1, 2, 3] { tx.send(val).unwrap(); } }); while let Ok(value) = rx.recv() { println!("{value}"); } }
Continues until the pattern fails to match.
for
Loops
The pattern follows for
:
fn main() { let v = vec!['a', 'b', 'c']; for (index, value) in v.iter().enumerate() { println!("{value} is at index {index}"); } }
Output:
$ cargo run
Compiling patterns v0.1.0 (file:///projects/patterns)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.52s
Running `target/debug/patterns`
a is at index 0
b is at index 1
c is at index 2
let
Statements
Every let
statement uses a pattern:
let x = 5; // x is a pattern
Formal syntax: let PATTERN = EXPRESSION;
Destructuring example:
fn main() { let (x, y, z) = (1, 2, 3); }
Pattern elements must match exactly:
fn main() {
let (x, y) = (1, 2, 3);
}
Error:
$ cargo run
Compiling patterns v0.1.0 (file:///projects/patterns)
error[E0308]: mismatched types
--> src/main.rs:2:9
|
2 | let (x, y) = (1, 2, 3);
| ^^^^^^ --------- this expression has type `({integer}, {integer}, {integer})`
| |
| expected a tuple with 3 elements, found one with 2 elements
|
= note: expected tuple `({integer}, {integer}, {integer})`
found tuple `(_, _)`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `patterns` (bin "patterns") due to 1 previous error
Function Parameters
Function parameters are patterns:
fn foo(x: i32) { // code goes here } fn main() {}
Destructuring in function signatures:
fn print_coordinates(&(x, y): &(i32, i32)) { println!("Current location: ({x}, {y})"); } fn main() { let point = (3, 5); print_coordinates(&point); }
Prints: Current location: (3, 5)
Closure parameters work the same way as function parameters.