]> git.proxmox.com Git - rustc.git/blob - src/doc/trpl/patterns.md
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / doc / trpl / patterns.md
1 % Patterns
2
3 Patterns are quite common in Rust. We use them in [variable
4 bindings][bindings], [match statements][match], and other places, too. Let’s go
5 on a whirlwind tour of all of the things patterns can do!
6
7 [bindings]: variable-bindings.html
8 [match]: match.html
9
10 A quick refresher: you can match against literals directly, and `_` acts as an
11 ‘any’ case:
12
13 ```rust
14 let x = 1;
15
16 match x {
17 1 => println!("one"),
18 2 => println!("two"),
19 3 => println!("three"),
20 _ => println!("anything"),
21 }
22 ```
23
24 This prints `one`.
25
26 # Multiple patterns
27
28 You can match multiple patterns with `|`:
29
30 ```rust
31 let x = 1;
32
33 match x {
34 1 | 2 => println!("one or two"),
35 3 => println!("three"),
36 _ => println!("anything"),
37 }
38 ```
39
40 This prints `one or two`.
41
42 # Ranges
43
44 You can match a range of values with `...`:
45
46 ```rust
47 let x = 1;
48
49 match x {
50 1 ... 5 => println!("one through five"),
51 _ => println!("anything"),
52 }
53 ```
54
55 This prints `one through five`.
56
57 Ranges are mostly used with integers and `char`s:
58
59 ```rust
60 let x = '💅';
61
62 match x {
63 'a' ... 'j' => println!("early letter"),
64 'k' ... 'z' => println!("late letter"),
65 _ => println!("something else"),
66 }
67 ```
68
69 This prints `something else`.
70
71 # Bindings
72
73 You can bind values to names with `@`:
74
75 ```rust
76 let x = 1;
77
78 match x {
79 e @ 1 ... 5 => println!("got a range element {}", e),
80 _ => println!("anything"),
81 }
82 ```
83
84 This prints `got a range element 1`. This is useful when you want to
85 do a complicated match of part of a data structure:
86
87 ```rust
88 #[derive(Debug)]
89 struct Person {
90 name: Option<String>,
91 }
92
93 let name = "Steve".to_string();
94 let mut x: Option<Person> = Some(Person { name: Some(name) });
95 match x {
96 Some(Person { name: ref a @ Some(_), .. }) => println!("{:?}", a),
97 _ => {}
98 }
99 ```
100
101 This prints `Some("Steve")`: We’ve bound the inner `name` to `a`.
102
103 If you use `@` with `|`, you need to make sure the name is bound in each part
104 of the pattern:
105
106 ```rust
107 let x = 5;
108
109 match x {
110 e @ 1 ... 5 | e @ 8 ... 10 => println!("got a range element {}", e),
111 _ => println!("anything"),
112 }
113 ```
114
115 # Ignoring variants
116
117 If you’re matching on an enum which has variants, you can use `..` to
118 ignore the value and type in the variant:
119
120 ```rust
121 enum OptionalInt {
122 Value(i32),
123 Missing,
124 }
125
126 let x = OptionalInt::Value(5);
127
128 match x {
129 OptionalInt::Value(..) => println!("Got an int!"),
130 OptionalInt::Missing => println!("No such luck."),
131 }
132 ```
133
134 This prints `Got an int!`.
135
136 # Guards
137
138 You can introduce ‘match guards’ with `if`:
139
140 ```rust
141 enum OptionalInt {
142 Value(i32),
143 Missing,
144 }
145
146 let x = OptionalInt::Value(5);
147
148 match x {
149 OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"),
150 OptionalInt::Value(..) => println!("Got an int!"),
151 OptionalInt::Missing => println!("No such luck."),
152 }
153 ```
154
155 This prints `Got an int!`.
156
157 If you’re using `if` with multiple patterns, the `if` applies to both sides:
158
159 ```rust
160 let x = 4;
161 let y = false;
162
163 match x {
164 4 | 5 if y => println!("yes"),
165 _ => println!("no"),
166 }
167 ```
168
169 This prints `no`, because the `if` applies to the whole of `4 | 5`, and not to
170 just the `5`, In other words, the the precedence of `if` behaves like this:
171
172 ```text
173 (4 | 5) if y => ...
174 ```
175
176 not this:
177
178 ```text
179 4 | (5 if y) => ...
180 ```
181
182 # ref and ref mut
183
184 If you want to get a [reference][ref], use the `ref` keyword:
185
186 ```rust
187 let x = 5;
188
189 match x {
190 ref r => println!("Got a reference to {}", r),
191 }
192 ```
193
194 This prints `Got a reference to 5`.
195
196 [ref]: references-and-borrowing.html
197
198 Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
199 keyword _creates_ a reference, for use in the pattern. If you need a mutable
200 reference, `ref mut` will work in the same way:
201
202 ```rust
203 let mut x = 5;
204
205 match x {
206 ref mut mr => println!("Got a mutable reference to {}", mr),
207 }
208 ```
209
210 # Destructuring
211
212 If you have a compound data type, like a [`struct`][struct], you can destructure it
213 inside of a pattern:
214
215 ```rust
216 struct Point {
217 x: i32,
218 y: i32,
219 }
220
221 let origin = Point { x: 0, y: 0 };
222
223 match origin {
224 Point { x, y } => println!("({},{})", x, y),
225 }
226 ```
227
228 [struct]: structs.html
229
230 We can use `:` to give a value a different name.
231
232 ```rust
233 struct Point {
234 x: i32,
235 y: i32,
236 }
237
238 let origin = Point { x: 0, y: 0 };
239
240 match origin {
241 Point { x: x1, y: y1 } => println!("({},{})", x1, y1),
242 }
243 ```
244
245 If we only care about some of the values, we don’t have to give them all names:
246
247 ```rust
248 struct Point {
249 x: i32,
250 y: i32,
251 }
252
253 let origin = Point { x: 0, y: 0 };
254
255 match origin {
256 Point { x, .. } => println!("x is {}", x),
257 }
258 ```
259
260 This prints `x is 0`.
261
262 You can do this kind of match on any member, not just the first:
263
264 ```rust
265 struct Point {
266 x: i32,
267 y: i32,
268 }
269
270 let origin = Point { x: 0, y: 0 };
271
272 match origin {
273 Point { y, .. } => println!("y is {}", y),
274 }
275 ```
276
277 This prints `y is 0`.
278
279 This ‘destructuring’ behavior works on any compound data type, like
280 [tuples][tuples] or [enums][enums].
281
282 [tuples]: primitive-types.html#tuples
283 [enums]: enums.html
284
285 # Mix and Match
286
287 Whew! That’s a lot of different ways to match things, and they can all be
288 mixed and matched, depending on what you’re doing:
289
290 ```rust,ignore
291 match x {
292 Foo { x: Some(ref name), y: None } => ...
293 }
294 ```
295
296 Patterns are very powerful. Make good use of them.