]>
Commit | Line | Data |
---|---|---|
0bf4aa26 XL |
1 | # Patterns |
2 | ||
3 | > **<sup>Syntax</sup>**\ | |
4 | > _Pattern_ :\ | |
5 | > [_LiteralPattern_]\ | |
6 | > | [_IdentifierPattern_]\ | |
7 | > | [_WildcardPattern_]\ | |
8 | > | [_RangePattern_]\ | |
9 | > | [_ReferencePattern_]\ | |
10 | > | [_StructPattern_]\ | |
11 | > | [_TupleStructPattern_]\ | |
12 | > | [_TuplePattern_]\ | |
13 | > | [_GroupedPattern_]\ | |
14 | > | [_SlicePattern_]\ | |
13cf67c4 XL |
15 | > | [_PathPattern_]\ |
16 | > | [_MacroInvocation_] | |
0bf4aa26 XL |
17 | |
18 | Patterns are used to match values against structures and to, | |
19 | optionally, bind variables to values inside these structures. They are also | |
20 | used in variable declarations and parameters for functions and closures. | |
21 | ||
22 | The pattern in the following example does four things: | |
23 | ||
24 | * Tests if `person` has the `car` field filled with something. | |
25 | * Tests if the person's `age` field is between 13 and 19, and binds its value to | |
26 | the `person_age` variable. | |
27 | * Binds a reference to the `name` field to the variable `person_name`. | |
28 | * Ignores the rest of the fields of `person`. The remaining fields can have any value and | |
29 | are not bound to any variables. | |
30 | ||
31 | ```rust | |
32 | # struct Car; | |
33 | # struct Computer; | |
34 | # struct Person { | |
35 | # name: String, | |
36 | # car: Option<Car>, | |
37 | # computer: Option<Computer>, | |
38 | # age: u8, | |
39 | # } | |
40 | # let person = Person { | |
41 | # name: String::from("John"), | |
42 | # car: Some(Car), | |
43 | # computer: None, | |
44 | # age: 15, | |
45 | # }; | |
46 | if let | |
47 | Person { | |
48 | car: Some(_), | |
49 | age: person_age @ 13..=19, | |
50 | name: ref person_name, | |
51 | .. | |
52 | } = person | |
53 | { | |
54 | println!("{} has a car and is {} years old.", person_name, person_age); | |
55 | } | |
56 | ``` | |
57 | ||
58 | Patterns are used in: | |
59 | ||
416331ca XL |
60 | * [`let` declarations](statements.md#let-statements) |
61 | * [Function](items/functions.md) and [closure](expressions/closure-expr.md) | |
0bf4aa26 | 62 | parameters |
416331ca XL |
63 | * [`match` expressions](expressions/match-expr.md) |
64 | * [`if let` expressions](expressions/if-expr.md) | |
65 | * [`while let` expressions](expressions/loop-expr.md#predicate-pattern-loops) | |
66 | * [`for` expressions](expressions/loop-expr.md#iterator-loops) | |
0bf4aa26 XL |
67 | |
68 | ## Destructuring | |
69 | ||
70 | Patterns can be used to *destructure* [structs], [enums], and [tuples]. | |
71 | Destructuring breaks up a value into its component pieces. The syntax used is | |
9fa01778 | 72 | almost the same as when creating such values. In a pattern whose [scrutinee] |
0bf4aa26 XL |
73 | expression has a `struct`, `enum` or `tuple` type, a placeholder (`_`) stands |
74 | in for a *single* data field, whereas a wildcard `..` stands in for *all* the | |
75 | remaining fields of a particular variant. When destructuring a data structure | |
76 | with named (but not numbered) fields, it is allowed to write `fieldname` as a | |
77 | shorthand for `fieldname: fieldname`. | |
78 | ||
79 | ```rust | |
80 | # enum Message { | |
81 | # Quit, | |
82 | # WriteString(String), | |
83 | # Move { x: i32, y: i32 }, | |
84 | # ChangeColor(u8, u8, u8), | |
85 | # } | |
86 | # let message = Message::Quit; | |
87 | match message { | |
88 | Message::Quit => println!("Quit"), | |
89 | Message::WriteString(write) => println!("{}", &write), | |
90 | Message::Move{ x, y: 0 } => println!("move {} horizontally", x), | |
91 | Message::Move{ .. } => println!("other move"), | |
92 | Message::ChangeColor { 0: red, 1: green, 2: _ } => { | |
93 | println!("color change, red: {}, green: {}", red, green); | |
94 | } | |
95 | }; | |
96 | ``` | |
97 | ||
98 | ## Refutability | |
99 | ||
100 | A pattern is said to be *refutable* when it has the possibility of not being matched | |
101 | by the value it is being matched against. *Irrefutable* patterns, on the other hand, | |
102 | always match the value they are being matched against. Examples: | |
103 | ||
104 | ```rust | |
105 | let (x, y) = (1, 2); // "(x, y)" is an irrefutable pattern | |
106 | ||
107 | if let (a, 3) = (1, 2) { // "(a, 3)" is refutable, and will not match | |
108 | panic!("Shouldn't reach here"); | |
109 | } else if let (a, 4) = (3, 4) { // "(a, 4)" is refutable, and will match | |
110 | println!("Matched ({}, 4)", a); | |
111 | } | |
112 | ``` | |
113 | ||
114 | ## Literal patterns | |
115 | ||
116 | > **<sup>Syntax</sup>**\ | |
117 | > _LiteralPattern_ :\ | |
118 | > [BOOLEAN_LITERAL]\ | |
119 | > | [CHAR_LITERAL]\ | |
120 | > | [BYTE_LITERAL]\ | |
121 | > | [STRING_LITERAL]\ | |
122 | > | [RAW_STRING_LITERAL]\ | |
123 | > | [BYTE_STRING_LITERAL]\ | |
124 | > | [RAW_BYTE_STRING_LITERAL]\ | |
125 | > | `-`<sup>?</sup> [INTEGER_LITERAL]\ | |
126 | > | `-`<sup>?</sup> [FLOAT_LITERAL] | |
127 | ||
416331ca XL |
128 | [BOOLEAN_LITERAL]: tokens.md#boolean-literals |
129 | [CHAR_LITERAL]: tokens.md#character-literals | |
130 | [BYTE_LITERAL]: tokens.md#byte-literals | |
131 | [STRING_LITERAL]: tokens.md#string-literals | |
132 | [RAW_STRING_LITERAL]: tokens.md#raw-string-literals | |
133 | [BYTE_STRING_LITERAL]: tokens.md#byte-string-literals | |
134 | [RAW_BYTE_STRING_LITERAL]: tokens.md#raw-byte-string-literals | |
135 | [INTEGER_LITERAL]: tokens.md#integer-literals | |
136 | [FLOAT_LITERAL]: tokens.md#floating-point-literals | |
0bf4aa26 XL |
137 | |
138 | _Literal patterns_ match exactly the same value as what is created by the | |
139 | literal. Since negative numbers are not [literals], literal patterns also | |
140 | accept an optional minus sign before the literal, which acts like the negation | |
141 | operator. | |
142 | ||
143 | <div class="warning"> | |
144 | ||
145 | Floating-point literals are currently accepted, but due to the complexity of comparing | |
146 | them, they are going to be forbidden on literal patterns in a future version of Rust (see | |
147 | [issue #41620](https://github.com/rust-lang/rust/issues/41620)). | |
148 | ||
149 | </div> | |
150 | ||
151 | Literal patterns are always refutable. | |
152 | ||
153 | Examples: | |
154 | ||
155 | ```rust | |
156 | for i in -2..5 { | |
157 | match i { | |
158 | -1 => println!("It's minus one"), | |
159 | 1 => println!("It's a one"), | |
160 | 2|4 => println!("It's either a two or a four"), | |
161 | _ => println!("Matched none of the arms"), | |
162 | } | |
163 | } | |
164 | ``` | |
165 | ||
166 | ## Identifier patterns | |
167 | ||
168 | > **<sup>Syntax</sup>**\ | |
169 | > _IdentifierPattern_ :\ | |
170 | > `ref`<sup>?</sup> `mut`<sup>?</sup> [IDENTIFIER] (`@` [_Pattern_] ) <sup>?</sup> | |
171 | ||
172 | Identifier patterns bind the value they match to a variable. The identifier | |
173 | must be unique within the pattern. The variable will shadow any variables of | |
174 | the same name in scope. The scope of the new binding depends on the context of | |
175 | where the pattern is used (such as a `let` binding or a `match` arm). | |
176 | ||
177 | Patterns that consist of only an identifier, possibly with a `mut`, match any value and | |
178 | bind it to that identifier. This is the most commonly used pattern in variable | |
179 | declarations and parameters for functions and closures. | |
180 | ||
181 | ```rust | |
182 | let mut variable = 10; | |
183 | fn sum(x: i32, y: i32) -> i32 { | |
184 | # x + y | |
185 | # } | |
186 | ``` | |
187 | ||
188 | To bind the matched value of a pattern to a variable, use the syntax `variable @ | |
189 | subpattern`. For example, the following binds the value 2 to `e` (not the | |
190 | entire range: the range here is a range subpattern). | |
191 | ||
192 | ```rust | |
193 | let x = 2; | |
194 | ||
195 | match x { | |
196 | e @ 1 ..= 5 => println!("got a range element {}", e), | |
197 | _ => println!("anything"), | |
198 | } | |
199 | ``` | |
200 | ||
201 | By default, identifier patterns bind a variable to a copy of or move from the | |
202 | matched value depending on whether the matched value implements [`Copy`]. | |
203 | This can be changed to bind to a reference by using the `ref` keyword, | |
204 | or to a mutable reference using `ref mut`. For example: | |
205 | ||
206 | ```rust | |
207 | # let a = Some(10); | |
208 | match a { | |
209 | None => (), | |
210 | Some(value) => (), | |
211 | } | |
212 | ||
213 | match a { | |
214 | None => (), | |
215 | Some(ref value) => (), | |
216 | } | |
217 | ``` | |
218 | ||
219 | In the first match expression, the value is copied (or moved). In the second match, | |
220 | a reference to the same memory location is bound to the variable value. This syntax is | |
221 | needed because in destructuring subpatterns the `&` operator can't be applied to | |
222 | the value's fields. For example, the following is not valid: | |
223 | ||
224 | ```rust,compile_fail | |
225 | # struct Person { | |
226 | # name: String, | |
227 | # age: u8, | |
228 | # } | |
229 | # let value = Person{ name: String::from("John"), age: 23 }; | |
230 | if let Person{name: &person_name, age: 18..=150} = value { } | |
231 | ``` | |
232 | ||
233 | To make it valid, write the following: | |
234 | ||
235 | ```rust | |
236 | # struct Person { | |
237 | # name: String, | |
238 | # age: u8, | |
239 | # } | |
240 | # let value = Person{ name: String::from("John"), age: 23 }; | |
241 | if let Person{name: ref person_name, age: 18..=150} = value { } | |
242 | ``` | |
243 | ||
244 | Thus, `ref` is not something that is being matched against. Its objective is | |
245 | exclusively to make the matched binding a reference, instead of potentially | |
246 | copying or moving what was matched. | |
247 | ||
248 | [Path patterns](#path-patterns) take precedence over identifier patterns. It is an error | |
249 | if `ref` or `ref mut` is specified and the identifier shadows a constant. | |
250 | ||
251 | ### Binding modes | |
252 | ||
253 | To service better ergonomics, patterns operate in different *binding modes* in | |
254 | order to make it easier to bind references to values. When a reference value is matched by | |
255 | a non-reference pattern, it will be automatically treated as a `ref` or `ref mut` binding. | |
256 | Example: | |
257 | ||
258 | ```rust | |
259 | let x: &Option<i32> = &Some(3); | |
260 | if let Some(y) = x { | |
261 | // y was converted to `ref y` and its type is &i32 | |
262 | } | |
263 | ``` | |
264 | ||
265 | *Non-reference patterns* include all patterns except bindings, [wildcard | |
266 | patterns](#wildcard-pattern) (`_`), [`const` patterns](#path-patterns) of reference types, | |
267 | and [reference patterns](#reference-patterns). | |
268 | ||
269 | If a binding pattern does not explicitly have `ref`, `ref mut`, or `mut`, then it uses the | |
270 | *default binding mode* to determine how the variable is bound. The default binding | |
271 | mode starts in "move" mode which uses move semantics. When matching a pattern, the | |
272 | compiler starts from the outside of the pattern and works inwards. Each time a reference | |
273 | is matched using a non-reference pattern, it will automatically dereference the value and | |
274 | update the default binding mode. References will set the default binding mode to `ref`. | |
275 | Mutable references will set the mode to `ref mut` unless the mode is already `ref` in | |
276 | which case it remains `ref`. If the automatically dereferenced value is still a reference, | |
277 | it is dereferenced and this process repeats. | |
278 | ||
279 | ## Wildcard pattern | |
280 | ||
281 | > **<sup>Syntax</sup>**\ | |
282 | > _WildcardPattern_ :\ | |
283 | > `_` | |
284 | ||
285 | The _wildcard pattern_ matches any value. It is used to ignore values when they don't | |
286 | matter. Inside other patterns it matches a single data field (as opposed to the `..` | |
287 | which matches the remaining fields). Unlike identifier patterns, it does not copy, move | |
288 | or borrow the value it matches. | |
289 | ||
290 | Examples: | |
291 | ||
292 | ```rust | |
293 | # let x = 20; | |
294 | let (a, _) = (10, x); // the x is always matched by _ | |
295 | # assert_eq!(a, 10); | |
296 | ||
297 | // ignore a function/closure param | |
298 | let real_part = |a: f64, _: f64| { a }; | |
299 | ||
300 | // ignore a field from a struct | |
301 | # struct RGBA { | |
302 | # r: f32, | |
303 | # g: f32, | |
304 | # b: f32, | |
305 | # a: f32, | |
306 | # } | |
307 | # let color = RGBA{r: 0.4, g: 0.1, b: 0.9, a: 0.5}; | |
308 | let RGBA{r: red, g: green, b: blue, a: _} = color; | |
309 | # assert_eq!(color.r, red); | |
310 | # assert_eq!(color.g, green); | |
311 | # assert_eq!(color.b, blue); | |
312 | ||
313 | // accept any Some, with any value | |
314 | # let x = Some(10); | |
315 | if let Some(_) = x {} | |
316 | ``` | |
317 | ||
318 | The wildcard pattern is always irrefutable. | |
319 | ||
320 | ## Range patterns | |
321 | ||
322 | > **<sup>Syntax</sup>**\ | |
323 | > _RangePattern_ :\ | |
324 | > _RangePatternBound_ `..=` _RangePatternBound_\ | |
325 | > | _RangePatternBound_ `...` _RangePatternBound_ | |
326 | > | |
327 | > _RangePatternBound_ :\ | |
328 | > [CHAR_LITERAL]\ | |
329 | > | [BYTE_LITERAL]\ | |
330 | > | `-`<sup>?</sup> [INTEGER_LITERAL]\ | |
331 | > | `-`<sup>?</sup> [FLOAT_LITERAL]\ | |
332 | > | [_PathInExpression_]\ | |
333 | > | [_QualifiedPathInExpression_] | |
334 | ||
335 | Range patterns match values that are within the closed range defined by its lower and | |
336 | upper bounds. For example, a pattern `'m'..='p'` will match only the values `'m'`, `'n'`, | |
337 | `'o'`, and `'p'`. The bounds can be literals or paths that point to constant values. | |
338 | ||
339 | A pattern a `..=` b must always have a ≤ b. It is an error to have a range pattern | |
340 | `10..=0`, for example. | |
341 | ||
342 | The `...` syntax is kept for backwards compatibility. | |
343 | ||
344 | Range patterns only work on scalar types. The accepted types are: | |
345 | ||
346 | * Integer types (u8, i8, u16, i16, usize, isize, etc.). | |
347 | * Character types (char). | |
348 | * Floating point types (f32 and f64). This is being deprecated and will not be available | |
349 | in a future version of Rust (see | |
350 | [issue #41620](https://github.com/rust-lang/rust/issues/41620)). | |
351 | ||
352 | Examples: | |
353 | ||
354 | ```rust | |
355 | # let c = 'f'; | |
356 | let valid_variable = match c { | |
357 | 'a'..='z' => true, | |
358 | 'A'..='Z' => true, | |
359 | 'α'..='ω' => true, | |
360 | _ => false, | |
361 | }; | |
362 | ||
363 | # let ph = 10; | |
364 | println!("{}", match ph { | |
365 | 0..=6 => "acid", | |
366 | 7 => "neutral", | |
367 | 8..=14 => "base", | |
368 | _ => unreachable!(), | |
369 | }); | |
370 | ||
371 | // using paths to constants: | |
372 | # const TROPOSPHERE_MIN : u8 = 6; | |
373 | # const TROPOSPHERE_MAX : u8 = 20; | |
374 | # | |
375 | # const STRATOSPHERE_MIN : u8 = TROPOSPHERE_MAX + 1; | |
376 | # const STRATOSPHERE_MAX : u8 = 50; | |
377 | # | |
378 | # const MESOSPHERE_MIN : u8 = STRATOSPHERE_MAX + 1; | |
379 | # const MESOSPHERE_MAX : u8 = 85; | |
380 | # | |
381 | # let altitude = 70; | |
382 | # | |
383 | println!("{}", match altitude { | |
384 | TROPOSPHERE_MIN..=TROPOSPHERE_MAX => "troposphere", | |
385 | STRATOSPHERE_MIN..=STRATOSPHERE_MAX => "stratosphere", | |
386 | MESOSPHERE_MIN..=MESOSPHERE_MAX => "mesosphere", | |
387 | _ => "outer space, maybe", | |
388 | }); | |
389 | ||
390 | # pub mod binary { | |
391 | # pub const MEGA : u64 = 1024*1024; | |
392 | # pub const GIGA : u64 = 1024*1024*1024; | |
393 | # } | |
394 | # let n_items = 20_832_425; | |
395 | # let bytes_per_item = 12; | |
396 | if let size @ binary::MEGA..=binary::GIGA = n_items * bytes_per_item { | |
397 | println!("It fits and occupies {} bytes", size); | |
398 | } | |
399 | ||
400 | # trait MaxValue { | |
401 | # const MAX: u64; | |
402 | # } | |
403 | # impl MaxValue for u8 { | |
404 | # const MAX: u64 = (1 << 8) - 1; | |
405 | # } | |
406 | # impl MaxValue for u16 { | |
407 | # const MAX: u64 = (1 << 16) - 1; | |
408 | # } | |
409 | # impl MaxValue for u32 { | |
410 | # const MAX: u64 = (1 << 32) - 1; | |
411 | # } | |
412 | // using qualified paths: | |
413 | println!("{}", match 0xfacade { | |
414 | 0 ..= <u8 as MaxValue>::MAX => "fits in a u8", | |
415 | 0 ..= <u16 as MaxValue>::MAX => "fits in a u16", | |
416 | 0 ..= <u32 as MaxValue>::MAX => "fits in a u32", | |
417 | _ => "too big", | |
418 | }); | |
419 | ``` | |
420 | ||
9fa01778 XL |
421 | Range patterns for (non-`usize` and -`isize`) integer and `char` types are irrefutable |
422 | when they span the entire set of possible values of a type. For example, `0u8..=255u8` | |
423 | is irrefutable. The range of values for an integer type is the closed range from its | |
424 | minimum to maximum value. The range of values for a `char` type are precisely those | |
425 | ranges containing all Unicode Scalar Values: `'\u{0000}'..='\u{D7FF}'` and | |
426 | `'\u{E000}'..='\u{10FFFF}'`. | |
0bf4aa26 XL |
427 | |
428 | ## Reference patterns | |
429 | ||
430 | > **<sup>Syntax</sup>**\ | |
431 | > _ReferencePattern_ :\ | |
432 | > (`&`|`&&`) `mut`<sup>?</sup> _Pattern_ | |
433 | ||
434 | Reference patterns dereference the pointers that are being matched | |
435 | and, thus, borrow them. | |
436 | ||
437 | For example, these two matches on `x: &i32` are equivalent: | |
438 | ||
439 | ```rust | |
440 | let int_reference = &3; | |
441 | ||
442 | let a = match *int_reference { 0 => "zero", _ => "some" }; | |
443 | let b = match int_reference { &0 => "zero", _ => "some" }; | |
444 | ||
445 | assert_eq!(a, b); | |
446 | ``` | |
447 | ||
448 | The grammar production for reference patterns has to match the token `&&` to match a | |
449 | reference to a reference because it is a token by itself, not two `&` tokens. | |
450 | ||
451 | Adding the `mut` keyword dereferences a mutable reference. The mutability must match the | |
452 | mutability of the reference. | |
453 | ||
454 | Reference patterns are always irrefutable. | |
455 | ||
456 | ## Struct patterns | |
457 | ||
458 | > **<sup>Syntax</sup>**\ | |
459 | > _StructPattern_ :\ | |
460 | > [_PathInExpression_] `{`\ | |
461 | > _StructPatternElements_ <sup>?</sup>\ | |
462 | > `}` | |
463 | > | |
464 | > _StructPatternElements_ :\ | |
465 | > _StructPatternFields_ (`,` | `,` _StructPatternEtCetera_)<sup>?</sup>\ | |
466 | > | _StructPatternEtCetera_ | |
467 | > | |
468 | > _StructPatternFields_ :\ | |
469 | > _StructPatternField_ (`,` _StructPatternField_) <sup>\*</sup> | |
470 | > | |
471 | > _StructPatternField_ :\ | |
472 | > [_OuterAttribute_] <sup>\*</sup>\ | |
473 | > (\ | |
474 | > [TUPLE_INDEX] `:` [_Pattern_]\ | |
475 | > | [IDENTIFIER] `:` [_Pattern_]\ | |
476 | > | `ref`<sup>?</sup> `mut`<sup>?</sup> [IDENTIFIER]\ | |
477 | > ) | |
478 | > | |
479 | > _StructPatternEtCetera_ :\ | |
480 | > [_OuterAttribute_] <sup>\*</sup>\ | |
481 | > `..` | |
482 | ||
416331ca | 483 | [_OuterAttribute_]: attributes.md |
f9f354fc | 484 | [TUPLE_INDEX]: tokens.md#tuple-index |
0bf4aa26 XL |
485 | |
486 | Struct patterns match struct values that match all criteria defined by its subpatterns. | |
487 | They are also used to [destructure](#destructuring) a struct. | |
488 | ||
489 | On a struct pattern, the fields are referenced by name, index (in the case of tuple | |
490 | structs) or ignored by use of `..`: | |
491 | ||
492 | ```rust | |
493 | # struct Point { | |
494 | # x: u32, | |
495 | # y: u32, | |
496 | # } | |
497 | # let s = Point {x: 1, y: 1}; | |
498 | # | |
499 | match s { | |
500 | Point {x: 10, y: 20} => (), | |
501 | Point {y: 10, x: 20} => (), // order doesn't matter | |
502 | Point {x: 10, ..} => (), | |
503 | Point {..} => (), | |
504 | } | |
505 | ||
506 | # struct PointTuple ( | |
507 | # u32, | |
508 | # u32, | |
509 | # ); | |
510 | # let t = PointTuple(1, 2); | |
511 | # | |
512 | match t { | |
513 | PointTuple {0: 10, 1: 20} => (), | |
514 | PointTuple {1: 10, 0: 20} => (), // order doesn't matter | |
515 | PointTuple {0: 10, ..} => (), | |
516 | PointTuple {..} => (), | |
517 | } | |
518 | ``` | |
519 | ||
520 | If `..` is not used, it is required to match all fields: | |
521 | ||
522 | ```rust | |
523 | # struct Struct { | |
524 | # a: i32, | |
525 | # b: char, | |
526 | # c: bool, | |
527 | # } | |
528 | # let mut struct_value = Struct{a: 10, b: 'X', c: false}; | |
529 | # | |
530 | match struct_value { | |
531 | Struct{a: 10, b: 'X', c: false} => (), | |
532 | Struct{a: 10, b: 'X', ref c} => (), | |
533 | Struct{a: 10, b: 'X', ref mut c} => (), | |
534 | Struct{a: 10, b: 'X', c: _} => (), | |
535 | Struct{a: _, b: _, c: _} => (), | |
536 | } | |
537 | ``` | |
538 | ||
539 | The `ref` and/or `mut` _IDENTIFIER_ syntax matches any value and binds it to | |
540 | a variable with the same name as the given field. | |
541 | ||
542 | ```rust | |
543 | # struct Struct { | |
544 | # a: i32, | |
545 | # b: char, | |
546 | # c: bool, | |
547 | # } | |
548 | # let struct_value = Struct{a: 10, b: 'X', c: false}; | |
549 | # | |
550 | let Struct{a: x, b: y, c: z} = struct_value; // destructure all fields | |
551 | ``` | |
552 | ||
553 | A struct pattern is refutable when one of its subpatterns is refutable. | |
554 | ||
555 | ## Tuple struct patterns | |
556 | ||
557 | > **<sup>Syntax</sup>**\ | |
558 | > _TupleStructPattern_ :\ | |
ba9703b0 | 559 | > [_PathInExpression_] `(` _TupleStructItems_<sup>?</sup> `)` |
0bf4aa26 XL |
560 | > |
561 | > _TupleStructItems_ :\ | |
562 | > [_Pattern_] ( `,` [_Pattern_] )<sup>\*</sup> `,`<sup>?</sup>\ | |
f9f354fc | 563 | > | ([_Pattern_] `,`)<sup>\*</sup> `..` (`,` [_Pattern_])<sup>*</sup> `,`<sup>?</sup> |
0bf4aa26 XL |
564 | |
565 | Tuple struct patterns match tuple struct and enum values that match all criteria defined | |
566 | by its subpatterns. They are also used to [destructure](#destructuring) a tuple struct or | |
567 | enum value. | |
568 | ||
569 | A tuple struct pattern is refutable when one of its subpatterns is refutable. | |
570 | ||
571 | ## Tuple patterns | |
572 | ||
573 | > **<sup>Syntax</sup>**\ | |
574 | > _TuplePattern_ :\ | |
575 | > `(` _TuplePatternItems_<sup>?</sup> `)` | |
576 | > | |
577 | > _TuplePatternItems_ :\ | |
578 | > [_Pattern_] `,`\ | |
579 | > | [_Pattern_] (`,` [_Pattern_])<sup>+</sup> `,`<sup>?</sup>\ | |
f9f354fc | 580 | > | ([_Pattern_] `,`)<sup>\*</sup> `..` (`,` [_Pattern_])<sup>*</sup> `,`<sup>?</sup> |
0bf4aa26 XL |
581 | |
582 | Tuple patterns match tuple values that match all criteria defined by its subpatterns. | |
583 | They are also used to [destructure](#destructuring) a tuple. | |
584 | ||
585 | This pattern is refutable when one of its subpatterns is refutable. | |
586 | ||
587 | ## Grouped patterns | |
588 | ||
589 | > **<sup>Syntax</sup>**\ | |
590 | > _GroupedPattern_ :\ | |
591 | > `(` [_Pattern_] `)` | |
592 | ||
593 | Enclosing a pattern in parentheses can be used to explicitly control the | |
594 | precedence of compound patterns. For example, a reference pattern next to a | |
595 | range pattern such as `&0..=5` is ambiguous and is not allowed, but can be | |
596 | expressed with parentheses. | |
597 | ||
598 | ```rust | |
599 | let int_reference = &3; | |
600 | match int_reference { | |
601 | &(0..=5) => (), | |
602 | _ => (), | |
603 | } | |
604 | ``` | |
605 | ||
606 | ## Slice patterns | |
607 | ||
608 | > **<sup>Syntax</sup>**\ | |
609 | > _SlicePattern_ :\ | |
610 | > `[` [_Pattern_] \(`,` [_Pattern_])<sup>\*</sup> `,`<sup>?</sup> `]` | |
611 | ||
612 | Slice patterns can match both arrays of fixed size and slices of dynamic size. | |
613 | ```rust | |
614 | // Fixed size | |
615 | let arr = [1, 2, 3]; | |
616 | match arr { | |
617 | [1, _, _] => "starts with one", | |
618 | [a, b, c] => "starts with something else", | |
619 | }; | |
620 | ``` | |
621 | ```rust | |
622 | // Dynamic size | |
623 | let v = vec![1, 2, 3]; | |
624 | match v[..] { | |
625 | [a, b] => { /* this arm will not apply because the length doesn't match */ } | |
626 | [a, b, c] => { /* this arm will apply */ } | |
627 | _ => { /* this wildcard is required, since the length is not known statically */ } | |
628 | }; | |
629 | ``` | |
630 | ||
631 | ## Path patterns | |
632 | ||
633 | > **<sup>Syntax</sup>**\ | |
634 | > _PathPattern_ :\ | |
635 | > [_PathInExpression_]\ | |
636 | > | [_QualifiedPathInExpression_] | |
637 | ||
638 | _Path patterns_ are patterns that refer either to constant values or | |
639 | to structs or enum variants that have no fields. | |
640 | ||
641 | Unqualified path patterns can refer to: | |
642 | ||
643 | * enum variants | |
644 | * structs | |
645 | * constants | |
646 | * associated constants | |
647 | ||
648 | Qualified path patterns can only refer to associated constants. | |
649 | ||
650 | Constants cannot be a union type. Struct and enum constants must have | |
651 | `#[derive(PartialEq, Eq)]` (not merely implemented). | |
652 | ||
653 | Path patterns are irrefutable when they refer to structs or an enum variant when the enum | |
654 | has only one variant or a constant whose type is irrefutable. They are refutable when they | |
655 | refer to refutable constants or enum variants for enums with multiple variants. | |
656 | ||
657 | [_GroupedPattern_]: #grouped-patterns | |
658 | [_IdentifierPattern_]: #identifier-patterns | |
659 | [_LiteralPattern_]: #literal-patterns | |
416331ca XL |
660 | [_MacroInvocation_]: macros.md#macro-invocation |
661 | [_PathInExpression_]: paths.md#paths-in-expressions | |
0bf4aa26 XL |
662 | [_PathPattern_]: #path-patterns |
663 | [_Pattern_]: #patterns | |
416331ca | 664 | [_QualifiedPathInExpression_]: paths.md#qualified-paths |
0bf4aa26 XL |
665 | [_RangePattern_]: #range-patterns |
666 | [_ReferencePattern_]: #reference-patterns | |
667 | [_SlicePattern_]: #slice-patterns | |
668 | [_StructPattern_]: #struct-patterns | |
669 | [_TuplePattern_]: #tuple-patterns | |
670 | [_TupleStructPattern_]: #tuple-struct-patterns | |
671 | [_WildcardPattern_]: #wildcard-pattern | |
672 | ||
416331ca XL |
673 | [`Copy`]: special-types-and-traits.md#copy |
674 | [IDENTIFIER]: identifiers.md | |
675 | [enums]: items/enumerations.md | |
676 | [literals]: expressions/literal-expr.md | |
677 | [structs]: items/structs.md | |
678 | [tuples]: types/tuple.md | |
679 | [scrutinee]: glossary.md#scrutinee |