Pattern matching
Patterns come in two forms: refutable and irrefutable.
Patterns that will match for any possible value passed are irrefutable. An example would be x in the statement let x = 5;
because x
matches anything and therefore cannot fail to match.
(Meaning it always will have a match.)
Patterns that can fail to match for some possible value are refutable. An example would be Some(x)
in the expression if let Some(x) = a_value
because if the value in the a_value
variable is None
rather than Some
, the Some(x)
pattern will not match.
Pattern matching type
let
- only irrefutable- fn param, closure - only irrefutable
match
exp - accept refutable and irrefutableif let
exp - accept refutable and irrefutablewhile let
exp - accept refutable and irrefutablefor
exp - only irrefutable
let
#![allow(unused)] fn main() { struct Point {x: isize, y: isize}; let (a, b) = (1, 2); let Point {x, y} = Point {x:3, y:4}; assert_eq!(3, x); assert_eq!(4, y); }
No need to write ref
?
Compiler helps you adding ref
when matching references with
non-references like expressions.
#![allow(unused)] fn main() { let x: Option<String> = Some("hello".into()); match &x { Some(s) => println!("{}", s), // nothing moves here, `s` is a &String, // the same as `Some(ref s) => ...`, with `ref` added by compiler behind the scene None => println!("nothing") } println!("{}", x.unwrap()); // x still owns the String }