3 We've made use of patterns a few times in the guide: first with `let` bindings,
4 then with `match` statements. Let's go on a whirlwind tour of all of the things
7 A quick refresher: you can match against literals directly, and `_` acts as an
16 3 => println!("three"),
17 _ => println!("anything"),
21 You can match multiple patterns with `|`:
27 1 | 2 => println!("one or two"),
28 3 => println!("three"),
29 _ => println!("anything"),
33 You can match a range of values with `...`:
39 1 ... 5 => println!("one through five"),
40 _ => println!("anything"),
44 Ranges are mostly used with integers and single characters.
46 If you're matching multiple things, via a `|` or a `...`, you can bind
47 the value to a name with `@`:
53 e @ 1 ... 5 => println!("got a range element {}", e),
54 _ => println!("anything"),
58 If you're matching on an enum which has variants, you can use `..` to
59 ignore the value and type in the variant:
67 let x = OptionalInt::Value(5);
70 OptionalInt::Value(..) => println!("Got an int!"),
71 OptionalInt::Missing => println!("No such luck."),
75 You can introduce *match guards* with `if`:
83 let x = OptionalInt::Value(5);
86 OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"),
87 OptionalInt::Value(..) => println!("Got an int!"),
88 OptionalInt::Missing => println!("No such luck."),
92 If you're matching on a pointer, you can use the same syntax as you declared it
99 &val => println!("Got a value: {}", val),
103 Here, the `val` inside the `match` has type `i32`. In other words, the left-hand
104 side of the pattern destructures the value. If we have `&5`, then in `&val`, `val`
107 If you want to get a reference, use the `ref` keyword:
113 ref r => println!("Got a reference to {}", r),
117 Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
118 keyword _creates_ a reference, for use in the pattern. If you need a mutable
119 reference, `ref mut` will work in the same way:
125 ref mut mr => println!("Got a mutable reference to {}", mr),
129 If you have a struct, you can destructure it inside of a pattern:
132 # #![allow(non_shorthand_field_patterns)]
138 let origin = Point { x: 0, y: 0 };
141 Point { x: x, y: y } => println!("({},{})", x, y),
145 If we only care about some of the values, we don't have to give them all names:
148 # #![allow(non_shorthand_field_patterns)]
154 let origin = Point { x: 0, y: 0 };
157 Point { x: x, .. } => println!("x is {}", x),
161 You can do this kind of match on any member, not just the first:
164 # #![allow(non_shorthand_field_patterns)]
170 let origin = Point { x: 0, y: 0 };
173 Point { y: y, .. } => println!("y is {}", y),
177 If you want to match against a slice or array, you can use `&`:
181 let v = vec!["match_this", "1"];
184 ["match_this", second] => println!("The second element is {}", second),
190 Whew! That's a lot of different ways to match things, and they can all be
191 mixed and matched, depending on what you're doing:
195 Foo { x: Some(ref name), y: None } => ...
199 Patterns are very powerful. Make good use of them.