]> git.proxmox.com Git - rustc.git/blob - src/doc/book/second-edition/src/ch18-03-pattern-syntax.md
New upstream version 1.23.0+dfsg1
[rustc.git] / src / doc / book / second-edition / src / ch18-03-pattern-syntax.md
1 ## All the Pattern Syntax
2
3 We’ve seen examples of many different kinds of patterns throughout the book, so
4 we’ll gather all the syntax valid in patterns in one place here, and why you
5 might want to use each of them.
6
7 <!-- We don't always go over why we might want to use them for each section
8 here, presumably because it's clear why it's useful. I might recommend you do
9 just add a line to each, since we've promised it, and just to really hammer the
10 point home. Definitely keep it short and sweet though, where it's pretty clear.
11 -->
12
13 ### Matching Literals
14
15 As we saw in Chapter 6, you can match patterns against literals directly. This
16 following code gives some examples:
17
18 ```rust
19 let x = 1;
20
21 match x {
22 1 => println!("one"),
23 2 => println!("two"),
24 3 => println!("three"),
25 _ => println!("anything"),
26 }
27 ```
28
29 This prints `one` since the value in `x` is 1. This is useful when you want to
30 take some action if you get a concrete value in particular.
31
32 ### Matching Named Variables
33
34 <!-- I found this next bit a little tougher to follow, I've tried to clarify in
35 this opening paragraph, connect it all up, can you please check it? -->
36 <!-- Yep! Looks good! /Carol -->
37
38 Named variables are irrefutable patterns that match any value, which we have
39 used many times before. There is a complication, however, when used in `match`
40 expressions. Because `match` starts a new scope, variables declared as part of
41 a pattern inside the `match` expression will shadow those with the same name
42 outside the `match` construct---as is the case with all variables. In Listing
43 18-11, we declare a variable named `x` with the value `Some(5)` and a variable
44 `y` with the value `10`. We then create a `match` expression on the value `x`.
45 Take a look at the patterns in the match arms and `println!` at the end, and
46 try to figure out what will be printed before running this code or reading
47 further:
48
49 <span class="filename">Filename: src/main.rs</span>
50
51 ```rust
52 fn main() {
53 let x = Some(5);
54 let y = 10;
55
56 match x {
57 Some(50) => println!("Got 50"),
58 Some(y) => println!("Matched, y = {:?}", y),
59 _ => println!("Default case, x = {:?}", x),
60 }
61
62 println!("at the end: x = {:?}, y = {:?}", x, y);
63 }
64 ```
65
66 <span class="caption">Listing 18-11: A `match` statement with an arm that
67 introduces a shadowed variable `y`</span>
68
69 Let’s walk through what happens when the `match` statement runs. The pattern in
70 the first match arm does not match the defined value of `x`, so we continue.
71
72 The pattern in the second match arm introduces a new variable name `y` that
73 will match any value inside a `Some` value. Because we’re in a new scope inside
74 the `match` expression, this is a new variable, and not the `y` we declared at
75 the beginning with the value 10. This new `y` binding will match any value
76 inside a `Some`, which is what we have in `x`. Therefore this `y` binds to the
77 inner value of the `Some` in `x`. That value is 5, and so the expression for
78 that arm executes and prints `Matched, y = 5`.
79
80 <!-- Below -- We haven't fully introduced the underscore yet, is there anything
81 else we could use for that final arm? -->
82 <!-- We have *used* the underscore briefly before, though-- we actually
83 introduced the underscore in chapter 6. There really isn't anything else that
84 we can put that will still have this example illustrating what we want to
85 illustrate. /Carol -->
86
87 If `x` had been a `None` value instead of `Some(5)`, the patterns in the first
88 two arms would not have matched, so we would have matched to the underscore. We
89 did not introduce the `x` variable in the pattern of that arm, so the `x` in
90 the expression is still the outer `x` that has not been shadowed. In this
91 hypothetical case, the `match` would print `Default case, x = None`.
92
93 Once the `match` expression is over, its scope ends, and so does the scope of
94 the inner `y`. The last `println!` produces `at the end: x = Some(5), y = 10`.
95
96 To create a `match` expression that compares the values of the outer `x` and
97 `y`, rather than introducing a shadowed variable, we would need to use a match
98 guard conditional instead. We’ll be talking about match guards later in this
99 section.
100
101 ### Multiple Patterns
102
103 In `match` expressions you can match multiple patterns using the `|` syntax,
104 which means *or*. For example, the following code matches the value of `x`
105 against the match arms, the first of which has an *or* option, meaning if the
106 value of `x` matches either of the values in that arm, it will run:
107
108 <!-- I've tried to flesh this out a bit, can you check? -->
109 <!-- Yep, it's fine! /Carol -->
110
111 ```rust
112 let x = 1;
113
114 match x {
115 1 | 2 => println!("one or two"),
116 3 => println!("three"),
117 _ => println!("anything"),
118 }
119 ```
120
121 This code will print `one or two`.
122
123 <!-- Is there a corresponding "and" operator? Is that worth tacking on here? -->
124 <!-- No, there is not-- how could one value match, say, 1 AND 2? Does it make
125 sense why there isn't an "and" operator? /Carol -->
126
127 ### Matching Ranges of Values with `...`
128
129 The `...` syntax allows you to match to an inclusive range of values. In the
130 following code, when a pattern matches any of the values within the range,
131 that arm will execute:
132
133 <!-- Above--this seems like it's true, that the range allows you to match to
134 just one of the values? If so, can you say how this differs to using the or
135 operator? -->
136 <!-- I'm not sure what you mean by "match to just one of the values". `...`
137 matches any value between the two specified endpoints, which I thought would be
138 clear by the text below the code, and I changed "just one of" to "any of the
139 values within" above, and mentioned what the equivalent "or" pattern would look
140 like below. Does that clear it up? /Carol -->
141
142 ```rust
143 let x = 5;
144
145 match x {
146 1 ... 5 => println!("one through five"),
147 _ => println!("something else"),
148 }
149 ```
150
151 If `x` is 1, 2, 3, 4, or 5, the first arm will match. This is more convenient
152 than using the `|` operator to express the same idea; instead of `1 ... 5` we
153 would have to specify `1 | 2 | 3 | 4 | 5` using `|`. Specifying a range instead
154 is much shorter, especially if we wanted to match, say, any number between 1
155 and 1,000!
156
157 Ranges are only allowed with numeric values or `char` values, because the
158 compiler checks that the range isn’t empty at compile time. `char` and numeric
159 values are the only types that Rust knows how to tell if a range is empty or
160 not.
161
162 <!-- why, because they are the only types with inherent order? -->
163 <!-- Nope, I've added the explanation /Carol -->
164
165 Here’s an example using ranges of `char` values:
166
167 ```rust
168 let x = 'c';
169
170 match x {
171 'a' ... 'j' => println!("early ASCII letter"),
172 'k' ... 'z' => println!("late ASCII letter"),
173 _ => println!("something else"),
174 }
175 ```
176
177 Rust can tell that `c` is within the first pattern’s range, and this will print
178 `early ASCII letter`.
179
180 ### Destructuring to Break Apart Values
181
182 <!-- I moved the definition of destructure earlier in the chapter, to when we
183 first use it -->
184 <!-- See my comment there; we first use destructure in chapter 3 /Carol -->
185
186 We can also use patterns to destructure structs, enums, tuples, and references
187 in order to use different parts of these values. Let’s go through each of those!
188
189 <!-- Above -- I think that's what we say later, that, we're skipping enums, but
190 please delete if not! You'll see my note where it comes up later -->
191 <!-- We actually had someone point out a detail we could cover regarding enums,
192 so we've added an enums section. /Carol -->
193
194 #### Destructuring Structs
195
196 Listing 18-12 shows a `Point` struct with two fields, `x` and `y`, that we can
197 break apart using a pattern with a `let` statement:
198
199 <span class="filename">Filename: src/main.rs
200
201 ```rust
202 struct Point {
203 x: i32,
204 y: i32,
205 }
206
207 fn main() {
208 let p = Point { x: 0, y: 7 };
209
210 let Point { x: a, y: b } = p;
211 assert_eq!(0, a);
212 assert_eq!(7, b);
213 }
214 ```
215
216 <span class="caption">Listing 18-12: Destructuring a struct’s fields into
217 separate variables</span>
218
219 <!-- I'm not sure I follow which part of this is the shorthand, what is it
220 shorthand for, and which syntax here counts as the shorthand? Can you slow this
221 down, talk it through a little more. Is the point of this section that we have
222 a shorthand for destructuring, or that we are able to destructure these items
223 with patterns at all? -->
224 <!-- I've reorganized this section to start with the non-shorthand instead, is
225 this clearer? /Carol -->
226
227 This code creates the variables `a` and `b` that match the values of the `x`
228 and `y` fields of the `p` variable.
229
230 This example shows that the names of the variable names in the pattern don’t
231 have to match the field names of the struct, but it’s common to want the
232 variable names to match the field names to make it easier to remember which
233 variables came from which fields. Because having variable names match the
234 fields is common, and because writing `let Point { x: x, y: y } = p;` contains
235 a lot of duplication, there’s a shorthand for patterns that match struct
236 fields: you only need to list the name of the struct field, and the variables
237 created from the pattern will have the same names. Listing 18-13 shows code
238 that behaves in the same way as the code in Listing 18-12, but the variables
239 created in the `let` pattern are `x` and `y` instead of `a` and `b`:
240
241 <span class="filename">Filename: src/main.rs</span>
242
243 ```rust
244 struct Point {
245 x: i32,
246 y: i32,
247 }
248
249 fn main() {
250 let p = Point { x: 0, y: 7 };
251
252 let Point { x, y } = p;
253 assert_eq!(0, x);
254 assert_eq!(7, y);
255 }
256 ```
257
258 <span class="caption">Listing 18-13: Destructuring struct fields using struct
259 field shorthand</span>
260
261 This code creates the variables `x` and `y` that match the `x` and `y` of the
262 `p` variable. The outcome is that the variables `x` and `y` contain the values
263 from the `p` struct.
264
265 We can also destructure with literal values as part of the struct pattern
266 rather than creating variables for all of the fields. This allows us to test
267 some of the fields for particular values while creating variables to
268 destructure the other fields.
269
270 Listing 18-14 shows a `match` statement that separates `Point` values into
271 three cases: points that lie directly on the `x` axis (which is true when `y =
272 0`), on the `y` axis (`x = 0`), or neither:
273
274 <!-- I'm not sure what you mean by "inner parts of a value" -- that we aren't
275 matching a whole value but part of it? -->
276 <!-- I've reworded, is this version clearer? /Carol -->
277
278 <span class="filename">Filename: src/main.rs</span>
279
280 ```rust
281 # struct Point {
282 # x: i32,
283 # y: i32,
284 # }
285 #
286 fn main() {
287 let p = Point { x: 0, y: 7 };
288
289 match p {
290 Point { x, y: 0 } => println!("On the x axis at {}", x),
291 Point { x: 0, y } => println!("On the y axis at {}", y),
292 Point { x, y } => println!("On neither axis: ({}, {})", x, y),
293 }
294 }
295 ```
296
297 <span class="caption">Listing 18-14: Destructuring and matching literal values
298 in one pattern</span>
299
300 The first arm will match any point that lies on the `x` axis by specifying that
301 the `y` field matches if its value matches the literal `0`. The pattern still
302 creates an `x` variable that we can use in the code for this arm. Similarly,
303 the second arm matches any point on the `y` axis by specifying that the `x`
304 field matches if its value is `0`, and creates a variable `y` for the value of
305 the `y` field. The third arm doesn’t specify any literals, so it matches any
306 other `Point` and creates variables for both the `x` and `y` fields.
307
308 In this example, the value `p` matches the second arm by virtue of `x`
309 containing a 0, so this will print `On the y axis at 7`.
310
311 #### Destructuring Enums
312
313 We’ve destructured enums before in this book, like in Listing 6-5 in Chapter 6
314 when we destructured an `Option<i32>`. One detail we haven’t mentioned
315 explicitly is that the pattern to destructure an enum should correspond to the
316 way the data stored within the enum is defined. For example, let’s take the
317 `Message` enum from Listing 6-2 and write a `match` with patterns that will
318 destructure each inner value in Listing 18-15:
319
320 <span class="filename">Filename: src/main.rs</span>
321
322 ```rust
323 enum Message {
324 Quit,
325 Move { x: i32, y: i32 },
326 Write(String),
327 ChangeColor(i32, i32, i32),
328 }
329
330 fn main() {
331 let msg = Message::ChangeColor(0, 160, 255);
332
333 match msg {
334 Message::Quit => {
335 println!("The Quit variant has no data to destructure.")
336 },
337 Message::Move { x: x, y: y } => {
338 println!(
339 "Move in the x direction {} and in the y direction {}",
340 x,
341 y
342 );
343 }
344 Message::Write(text) => println!("Text message: {}", text),
345 Message::ChangeColor(r, g, b) => {
346 println!(
347 "Change the color to red {}, green {}, and blue {}",
348 r,
349 g,
350 b
351 )
352 }
353 }
354 }
355 ```
356
357 <span class="caption">Listing 18-15: Destructuring enum variants that hold
358 different kinds of values</span>
359
360 This code will print `Change the color to red 0, green 160, and blue 255`. Try
361 changing the value of `msg` to see the code from the other arms run.
362
363 For enum variants without any data like `Message::Quit`, we can’t destructure
364 the value any further. We can only match on the literal `Message::Quit` value,
365 and there are no variables in that pattern.
366
367 For struct-like enum variants such as `Message::Move`, we can use a pattern
368 similar to the pattern we specify to match structs. After the variant name, we
369 place curly brackets and then list the fields with variables so that we break
370 apart the pieces to use in the code for this arm.
371
372 For tuple-like enum variants like `Message::Write`, that holds a tuple with one
373 element, and `Message::ChangeColor` that holds a tuple with three elements, the
374 pattern is similar to the pattern we specify to match tuples. The number of
375 variables in the pattern must match the number of elements in the variant we’re
376 matching.
377
378 #### Destructuring References
379
380 When the value we’re matching to our pattern contains a reference, we need to
381 destructure the reference from the value, which we can do can by specifying a
382 `&` in the pattern. This lets us get a variable holding the value that the
383 reference points to rather than getting a variable that holds the reference.
384
385 <!-- What does it mean, to separate the reference and the value, precisely? So
386 that we specify Rust use the value in place of the reference? And what does &
387 here do, tell Rust to follow the reference to the value itself, rather than
388 work on the reference?-->
389 <!-- Yes, pretty much. I've tried rewording, is this clearer? /Carol -->
390
391 This is especially useful in closures where we have iterators that iterate over
392 references, but we want to use the values in the closure rather than the
393 references.
394
395 The example in Listing 18-16 iterates over references to `Point` instances in a
396 vector, and destructures both the reference and the struct so we can perform
397 calculations on the `x` and `y` values easily:
398
399 ```rust
400 # struct Point {
401 # x: i32,
402 # y: i32,
403 # }
404 #
405 let points = vec![
406 Point { x: 0, y: 0 },
407 Point { x: 1, y: 5 },
408 Point { x: 10, y: -3 },
409 ];
410
411 let sum_of_squares: i32 = points
412 .iter()
413 .map(|&Point { x, y }| x * x + y * y)
414 .sum();
415 ```
416
417 <span class="caption">Listing 18-16: Destructuring a reference to a struct into
418 the struct field values</span>
419
420 <!-- and what do we actually get, instead of the error? -->
421 <!-- Added explanation text below /Carol -->
422
423 This code results in the value 135 in the variable `sum_of_squares`, which is
424 the result from squaring the `x` value and the `y` value, adding those
425 together, and then adding the result for each `Point` in the `points` vector to
426 get one number.
427
428 If we had not included the `&` in `&Point { x, y }` we’d get a type mismatch
429 error, because `iter` would then iterate over references to the items in the
430 vector rather than the values themselves. The error would look like this:
431
432 ```text
433 error[E0308]: mismatched types
434 -->
435 |
436 14 | .map(|Point { x, y }| x * x + y * y)
437 | ^^^^^^^^^^^^ expected &Point, found struct `Point`
438 |
439 = note: expected type `&Point`
440 found type `Point`
441 ```
442
443 This tells us that Rust was expecting our closure to match `&Point`, but we
444 tried to match directly to a `Point` value, and not a reference to a `Point`.
445
446 #### Destructuring Structs and Tuples
447
448 We can mix, match, and nest destructuring patterns in even more complex way.
449 Here’s an example of a complicated destructure, where we nest structs and
450 tuples inside a tuple, and destructure all the primitive values out:
451
452 ```rust
453 # struct Point {
454 # x: i32,
455 # y: i32,
456 # }
457 #
458 let ((feet, inches), Point {x, y}) = ((3, 10), Point { x: 3, y: -10 });
459 ```
460
461 This lets us break complex types into their component parts so that we can use
462 the values we’re interested in separately.
463
464 <!-- Can you round up the destructuring section here before we move on. For
465 this bit, maybe say explicitly what this would be useful for -->
466 <!-- Done /Carol -->
467
468 Destructuring with patterns is a convenient way to use pieces of values, such
469 as the value from each field in a struct, separately from each other.
470
471 ### Ignoring Values in a Pattern
472
473 We’ve seen that it’s sometimes useful to ignore values in a pattern, such as in
474 the last arm of a `match` to give us a catch-all that doesn’t actually do
475 anything, but does account for all remaining possible values. There are a few
476 ways to ignore entire values or parts of values in a pattern: using the `_`
477 pattern (which we’ve seen), using the `_` pattern within another pattern, using
478 a name that starts with an underscore, or using `..` to ignore remaining parts
479 of a value. Let’s explore how and why to do each of these.
480
481 #### Ignoring an Entire Value with `_`
482
483 We’ve used the underscore as a wildcard pattern that will match any value but
484 not bind to the value. While the underscore pattern is especially useful as the
485 last arm in a `match` expression, we can use it in any pattern, including
486 function parameters, as shown in Listing 18-17:
487
488 <span class="filename">Filename: src/main.rs</span>
489
490 ```rust
491 fn foo(_: i32, y: i32) {
492 println!("This code only uses the y parameter: {}", y);
493 }
494
495 fn main() {
496 foo(3, 4);
497 }
498 ```
499
500 <span class="caption">Listing 18-17: Using `_` in a function signature</span>
501
502 <!-- What is this doing exactly, can you help the reader out here? Are we
503 letting the function run without a parameter at all? I'm not sure the purpose
504 clear enough at the moment -->
505 <!-- Done /Carol -->
506
507 This code will completely ignore the value passed as the first argument, 3, and
508 will print out `This code only uses the y parameter: 4`. In most cases when you
509 no longer need a particular function parameter, you would change the signature
510 so it doesn’t include the unused parameter.
511
512 Ignoring a function parameter can be especially useful in some cases, such as
513 when implementing a trait, when you need a certain type signature but the
514 function body in your implementation doesn’t need one of the parameters. The
515 compiler will then not warn about unused function parameters, as it would if we
516 used a name instead.
517
518 #### Ignoring Parts of a Value with a Nested `_`
519
520 <!-- When would we want to do this? -->
521 <!-- Done, moved the explanation up and made the example have a bit more
522 motivation /Carol -->
523
524 We can also use `_` inside of another pattern to ignore just part of a value,
525 when we only want to test for part of a value but have no use for the other
526 parts in the corresponding code we want to run. Listing 18-18 shows code
527 responsible for giving a setting a value. The business requirements are that
528 the user should not be allowed to overwrite an existing customization of a
529 setting, but can unset the setting and can give the setting a value if it is
530 currently unset.
531
532 ```rust
533 let mut setting_value = Some(5);
534 let new_setting_value = Some(10);
535
536 match (setting_value, new_setting_value) {
537 (Some(_), Some(_)) => {
538 println!("Can't overwrite an existing customized value");
539 }
540 _ => {
541 setting_value = new_setting_value;
542 }
543 }
544
545 println!("setting is {:?}", setting_value);
546 ```
547
548 <span class="caption">Listing 18-18: Using an underscore within patterns that
549 match `Some` variants when we don’t need to use the value inside the
550 `Some`</span>
551
552 This code will print `Can't overwrite an existing customized value` and then
553 `setting is Some(5)`. In the first match arm, we don’t need to match on or use
554 the values inside either `Some` variant; the important part we need to test for
555 is the case when both `setting_value` and `new_setting_value` are the `Some`
556 variant. In that case, we want to print out why we’re not changing
557 `setting_value`, and we don’t change it.
558
559 In all other cases (if either `setting_value` or `new_setting_value` are
560 `None`), which is expressed by the `_` pattern in the second arm, we do want to
561 allow `new_setting_value` to become `setting_value`.
562
563 <!-- So when we need to match but don't actually need the value, is that what
564 we're saying? -->
565 <!-- Yes /Carol -->
566
567 We can also use underscores in multiple places within one pattern to ignore
568 particular values, as shown in Listing 18-19 where we’re ignoring the second
569 and fourth values in a tuple of five items:
570
571 ```rust
572 let numbers = (2, 4, 8, 16, 32);
573
574 match numbers {
575 (first, _, third, _, fifth) => {
576 println!("Some numbers: {}, {}, {}", first, third, fifth)
577 },
578 }
579 ```
580
581 <span class="caption">Listing 18-19: Ignoring multiple parts of a tuple</span>
582
583 This will print `Some numbers: 2, 8, 32`, and the values 4 and 16 will be
584 ignored.
585
586 #### Ignoring an Unused Variable by Starting its Name with an Underscore
587
588 If you create a variable but don’t use it anywhere, Rust will usually issue a
589 warning, since that could be a bug. Sometimes, though, it’s useful to create a
590 variable you won’t use yet, like if you’re prototyping or just starting a
591 project. In this situation you’ll want to tell Rust not to warn you about the
592 unused variable, which you can do by starting the name of the variable with an
593 underscore. In Listing 18-20 we create two unused variables, but when we run
594 this code we should only get a warning about one of them.
595
596 <span class="filename">Filename: src/main.rs</span>
597
598 ```rust
599 fn main() {
600 let _x = 5;
601 let y = 10;
602 }
603 ```
604
605 <span class="caption">Listing 18-20: Starting a variable name with an
606 underscore in order to not get unused variable warnings</span>
607
608 Here we get a warning about not using the variable `y`, but not about not using
609 the variable preceded by the underscore.
610
611 Note that there is a subtle difference between using only `_` and using a name
612 that starts with an underscore. Something like `_x` still binds the value to
613 the variable, whereas `_` doesn’t bind at all. To show a case where this
614 distinction matters, Listing 18-21 will provide us with an error.
615
616 ```rust,ignore
617 let s = Some(String::from("Hello!"));
618
619 if let Some(_s) = s {
620 println!("found a string");
621 }
622
623 println!("{:?}", s);
624 ```
625
626 <span class="caption">Listing 18-21: An unused variable starting with an
627 underscore still binds the value, which may take ownership of the value</span>
628
629 We’ll receive an error because the `s` value will still be moved into `_s`,
630 which prevents us from using `s` again. Using the underscore by itself,
631 however, doesn’t ever bind to the value. Listing 18-22 will compile without any
632 errors since `s` does not get moved into `_`:
633
634 ```rust
635 let s = Some(String::from("Hello!"));
636
637 if let Some(_) = s {
638 println!("found a string");
639 }
640
641 println!("{:?}", s);
642 ```
643
644 <span class="caption">Listing 18-22: Using underscore does not bind the
645 value</span>
646
647 This works just fine; because we never bind `s` to anything, it isn’t moved.
648
649 #### Ignoring Remaining Parts of a Value with `..`
650
651 With values that have many parts, we can use the `..` syntax to use only a few
652 parts and ignore the rest, while avoiding having to list underscores for each
653 ignored value. The `..` pattern will ignore any parts of a value that we
654 haven’t explicitly matched in the rest of the pattern. In Listing 18-23, we
655 have a `Point` struct that holds a coordinate in three dimensional space. In
656 the `match` expression, we want to operate only on the `x` coordinate and
657 ignore the values in the `y` and `z` fields:
658
659 ```rust
660 struct Point {
661 x: i32,
662 y: i32,
663 z: i32,
664 }
665
666 let origin = Point { x: 0, y: 0, z: 0 };
667
668 match origin {
669 Point { x, .. } => println!("x is {}", x),
670 }
671 ```
672
673 <span class="caption">Listing 18-23: Ignoring all fields of a `Point` except
674 for `x` by using `..`</span>
675
676 We list the `x` value, and then just include the `..` pattern. This is quicker
677 than having to list out `y: _` and `z: _`, particularly when working with
678 structs that have lots of fields, in situations where only one or two fields
679 are relevant.
680
681 `..` will expand to as many values as it needs to be. Listing 18-24 shows a use
682 of `..` with a tuple:
683
684 <span class="filename">Filename: src/main.rs</span>
685
686 ```rust
687 fn main() {
688 let numbers = (2, 4, 8, 16, 32);
689
690 match numbers {
691 (first, .., last) => {
692 println!("Some numbers: {}, {}", first, last);
693 },
694 }
695 }
696 ```
697
698 <span class="caption">Listing 18-24: Matching only the first and last values in
699 a tuple and ignoring all other values</span>
700
701 Here, we have the first and last value matched with `first` and `last`. The
702 `..` will match and ignore everything in the middle.
703
704 Using `..` must be unambiguous, however. If it is not clear which values are
705 intended for matching, and which to be ignored, Rust will error. Listing 18-25
706 shows an example of using `..` ambiguously that will not compile due to this
707 ambiguity:
708
709 <span class="filename">Filename: src/main.rs</span>
710
711 ```rust,ignore
712 fn main() {
713 let numbers = (2, 4, 8, 16, 32);
714
715 match numbers {
716 (.., second, ..) => {
717 println!("Some numbers: {}", second)
718 },
719 }
720 }
721 ```
722
723 <span class="caption">Listing 18-25: An attempt to use `..` in a way that is
724 ambiguous</span>
725
726 If we compile this example, we get this error:
727
728 ```text
729 error: `..` can only be used once per tuple or tuple struct pattern
730 --> src/main.rs:5:22
731 |
732 5 | (.., second, ..) => {
733 | ^^
734 ```
735
736 It’s not possible for Rust to determine how many values in the tuple to ignore
737 before matching a value with `second`, and then how many further values to
738 ignore after that. This code could mean that we intend to ignore 2, bind
739 `second` to 4, then ignore 8, 16, and 32; or we could mean that we want to
740 ignore 2 and 4, bind `second` to 8, then ignore 16 and 32, and so forth. The
741 variable name `second` doesn’t mean anything special to Rust, so we get a
742 compiler error since using `..` in two places like this is ambiguous.
743
744 ### `ref` and `ref mut` to Create References in Patterns
745
746 Here we’ll look at using `ref` to make references so ownership of the values
747 isn’t moved to variables in the pattern. Usually, when you match against a
748 pattern, the variables introduced by the pattern are bound to a value. Rust’s
749 ownership rules mean the value will be moved into the `match`, or wherever
750 you’re using the pattern. Listing 18-26 shows an example of a `match` that has
751 a pattern with a variable, and then another usage of the entire value after the
752 `match`. This will fail to compile because ownership of part of the
753 `robot_name` value is transferred to the `name` variable in the pattern of the
754 first `match` arm:
755
756 <!-- Can you lay out what is supposed to happen with this code, that doesn't
757 work? -->
758 <!-- Done /Carol -->
759
760 ```rust,ignore
761 let robot_name = Some(String::from("Bors"));
762
763 match robot_name {
764 Some(name) => println!("Found a name: {}", name),
765 None => (),
766 }
767
768 println!("robot_name is: {:?}", robot_name);
769 ```
770
771 <span class="caption">Listing 18-26: Creating a variable in a match arm pattern
772 takes ownership of the value</span>
773
774 This example will fail because the value inside `Some` in `robot_name` is moved
775 to within the `match` when `name` binds to that value. Because ownership of
776 part of `robot_name` has been moved to `name`, we can no longer use
777 `robot_name` in the `println!` after the `match` because `robot_name` no longer
778 has ownership.
779
780 <!-- Above -- why will that make it fail, because the bind is then invalid? -->
781 <!-- Yes, I've clarified a bit /Carol -->
782
783 <!--Below -- Is this then the solution, introducing &? I assume so, because we
784 don’t have & in the example above, but the connection isn't clear -->
785 <!-- No, the solution is introducing `ref`. I've clarified /Carol -->
786
787 In order to fix this code, we want to have the `Some(name)` pattern borrow that
788 part of `robot_name` rather than taking ownership. Outside of patterns, we’ve
789 seen that the way to borrow a value is to create a reference using `&`, so you
790 may think the solution is changing `Some(name)` to `Some(&name)`.
791
792 However, we saw in the “Destructuring to Break Apart Values” section that `&`
793 in patterns does not *create* a reference, it *matches* an existing reference
794 in the value. Because `&` already has that meaning in patterns, we can’t use
795 `&` to create a reference in a pattern.
796
797 Instead, to create a reference in a pattern, we do this by using the `ref`
798 keyword before the new variable, as shown in Listing 18-27:
799
800 ```rust
801 let robot_name = Some(String::from("Bors"));
802
803 match robot_name {
804 Some(ref name) => println!("Found a name: {}", name),
805 None => (),
806 }
807
808 println!("robot_name is: {:?}", robot_name);
809 ```
810
811 <span class="caption">Listing 18-27: Creating a reference so that a pattern
812 variable does not take ownership of a value</span>
813
814 This example will compile because the value in the `Some` variant in
815 `robot_name` is not moved into the `match`; the `match` only took a reference
816 to the data in `robot_name` rather than moving it.
817
818 To create a mutable reference in order to be able to mutate a value matched in
819 a pattern, use `ref mut` instead of `&mut` for the same reason that we use
820 `ref` instead of `&`: `&mut` in patterns is for matching existing mutable
821 references, not creating new ones. Listing 18-28 shows an example of a pattern
822 creating a mutable reference:
823
824 ```rust
825 let mut robot_name = Some(String::from("Bors"));
826
827 match robot_name {
828 Some(ref mut name) => *name = String::from("Another name"),
829 None => (),
830 }
831
832 println!("robot_name is: {:?}", robot_name);
833 ```
834
835 <span class="caption">Listing 18-28: Creating a mutable reference to a value as
836 part of a pattern using `ref mut`</span>
837
838 This example will compile and print `robot_name is: Some("Another name")`.
839 Because `name` is a mutable reference, we need to dereference within the match
840 arm code using the `*` operator in order to be able to mutate the value.
841
842 ### Extra Conditionals with Match Guards
843
844 <!-- Can you give a full definition of a match guard here, and what we use it
845 for, before covering how to do it? -->
846
847 A *match guard* is an additional `if` condition specified after the pattern in
848 a `match` arm that also must match if the pattern matches in order for that arm
849 to be chosen. Match guards are useful for expressing more complex ideas than a
850 pattern alone allows.
851
852 The condition can use variables created in the pattern. Listing 18-29 shows a
853 `match` where the first arm has the pattern `Some(x)` and then also has a match
854 guard of `if x < 5`:
855
856 ```rust
857 let num = Some(4);
858
859 match num {
860 Some(x) if x < 5 => println!("less than five: {}", x),
861 Some(x) => println!("{}", x),
862 None => (),
863 }
864 ```
865
866 <span class="caption">Listing 18-29: Adding a match guard to a pattern</span>
867
868 This example will print `less than five: 4`. When `num` is compared to the
869 pattern in the first arm, it matches since `Some(4)` matches `Some(x)`. Then
870 the match guard checks to see if the value in `x` is less than 5, and because 4
871 is less than 5, the first arm is selected.
872
873 If `num` had been `Some(10)` instead, the match guard in the first arm would
874 have been false since 10 is not less than 5. Rust would then go to the second
875 arm, which would match because the second arm does not have a match guard and
876 therefore matches any `Some` variant.
877
878 There’s no way to express the `if x < 5` condition within a pattern, so the
879 match guard has given us the ability to express this logic.
880
881 <!-- I think we need this spelled out, can you say what it is the match guard
882 is doing here? I've had a guess above, but I think it needs your review! -->
883 <!-- Reviewed and tweaked a bit! /Carol -->
884
885 In Listing 18-11, we mentioned that we could use match guards to solve our
886 pattern shadowing problem, where a new variable was created inside the pattern
887 in the `match` expression instead of using the variable outside the `match`.
888 That new variable meant we couldn’t test against the value that the outer
889 variable had. Listing 18-30 shows how we can use a match guard to fix this:
890
891 <!-- Can you check this above -- I've tried to paraphrase the final paragraph
892 from that section. -->
893 <!-- Checked and reworded a bit /Carol -->
894
895 <span class="filename">Filename: src/main.rs</span>
896
897 ```rust
898 fn main() {
899 let x = Some(5);
900 let y = 10;
901
902 match x {
903 Some(50) => println!("Got 50"),
904 Some(n) if n == y => println!("Matched, n = {:?}", n),
905 _ => println!("Default case, x = {:?}", x),
906 }
907
908 println!("at the end: x = {:?}, y = {:?}", x, y);
909 }
910 ```
911
912 <span class="caption">Listing 18-30: Using a match guard to test for equality
913 with an outer variable</span>
914
915 This will now print `Default case, x = Some(5)`. The pattern in the second
916 match arm is now not introducing a new variable `y` that would shadow the outer
917 `y`, meaning we can use the outer `y` in the match guard. Instead of specifying
918 the pattern as `Some(y)`, which would have shadowed the outer `y`, we specify
919 `Some(n)`. This creates a new variable `n` that does not shadow anything
920 because there is no `n` variable outside the `match`.
921
922 In the match guard, `if n == y`, this is not a pattern and therefore does not
923 introduce new variables. This `y` *is* the outer `y` rather than a new shadowed
924 `y`, and we can express the idea that we’re looking for a value that has the
925 same value as the outer `y` by comparing `n` to `y`.
926
927 <!-- Why is this one not introducing a new variable y but 18-10 was? Instead we
928 create a new variable n and then compare it to the outer y, is that it? In
929 which case, I'm not understanding how we get n from destructuring x, can you
930 lay this out?-->
931 <!-- I've elaborated a bit, does this clear it up? /Carol -->
932
933 You can also use the or operator `|` in a match guard to specify multiple
934 patterns, and the match guard condition will apply to all of the patterns.
935 Listing 18-31 shows the precedence of combining a match guard with a pattern
936 that uses `|`. The important part of this example is that the `if y` match
937 guard applies to 4, 5, *and* 6, even though it might look like `if y` only
938 applies to 6:
939
940 <!-- What's the match condition actually doing here, with y having a value of
941 `false`? Can you let us know how that's being applied to all the values in that
942 match arm? -->
943 <!-- The point of the example here is to illustrate operator precedence, that
944 this code might look like it's saying `4 | 5 | (6 if y)` but it's actually
945 saying `(4 | 5 | 6) if y`. I've tried to elaborate above and below, does that
946 make sense now? /Carol -->
947
948 ```rust
949 let x = 4;
950 let y = false;
951
952 match x {
953 4 | 5 | 6 if y => println!("yes"),
954 _ => println!("no"),
955 }
956 ```
957
958 <span class="caption">Listing 18-31: Combining multiple patterns with a match
959 guard</span>
960
961 The match condition states that the arm only matches if the value of `x` is
962 equal to 4, 5, or 6 *and* if `y` is `true`. What happens when this code runs is
963 that the pattern of the first arm matches because `x` is 4, but the match guard
964 `if y` is false, so the first arm is not chosen. The code moves on to the
965 second arm, which does match, and this program prints `no`.
966
967 <!-- Is this what we mean, if 4 or 5 or 6 being equal to x is false, run the
968 first arm? And so, because it's applying that to all of the values (including
969 4), the second arm is run and not the first? -->
970 <!-- It seems like `if y` was confusing, I've tried to spell it out a bit more.
971 Does this make sense now? /Carol -->
972
973 This is because the `if` condition applies to the whole pattern `4 | 5 | 6`,
974 and not only to the last value `6`. In other words, the precedence of a match
975 guard in relation to a pattern behaves like this:
976
977 ```text
978 (4 | 5 | 6) if y => ...
979 ```
980
981 rather than this:
982
983 ```text
984 4 | 5 | (6 if y) => ...
985 ```
986
987 We can tell this from what happened when we ran the code: if the match guard
988 was only applied to the final value in the list of values specified using the
989 `|` operator, the arm would have matched and the program would have printed
990 `yes`.
991
992 ### `@` Bindings
993
994 <!-- Below - use @ to what, can you say explicitly what it does. Also what the
995 name of the operator is? -->
996 <!-- I don't think it has a name other than "the at operator". And we tried to
997 say what it does-- it creates a variable at the same time as letting us test
998 it, I've tried rewording a bit but I'm not sure why that wasn't explicit
999 enough, can you clarify if this still doesn't make sense? /Carol -->
1000
1001 The at operator, `@`, lets us create a variable that holds a value at the same
1002 time we’re testing that value to see if it matches a pattern. Listing 18-32
1003 shows an example where we want to test that a `Message::Hello` `id` field is
1004 within the range `3...7` but also be able to bind the value to the variable
1005 `id_variable` so that we can use it in the code associated with the arm. We
1006 could have named `id_variable` `id`, the same as the field, but for the
1007 purposes of this example we’ve chosen to give it a different name:
1008
1009 ```rust
1010 enum Message {
1011 Hello { id: i32 },
1012 }
1013
1014 let msg = Message::Hello { id: 5 };
1015
1016 match msg {
1017 Message::Hello { id: id_variable @ 3...7 } => {
1018 println!("Found an id in range: {}", id_variable)
1019 },
1020 Message::Hello { id: 10...12 } => {
1021 println!("Found an id in another range")
1022 },
1023 Message::Hello { id } => {
1024 println!("Found some other id: {}", id)
1025 },
1026 }
1027 ```
1028
1029 <span class="caption">Listing 18-32: Using `@` to bind to a value in a pattern
1030 while also testing it</span>
1031
1032 This example will print `Found an id in range: 5`. By specifying `id_variable
1033 @` before the range `3...7`, we’re capturing whatever value matched the range
1034 while also testing that the value matched the range pattern.
1035
1036 In the second arm where we only have a range specified in the pattern, the code
1037 associated with the arm doesn’t have a variable that contains the actual value
1038 of the `id` field. The `id` field’s value could have been 10, 11, or 12 but the
1039 code that goes with that pattern doesn’t know which one and isn’t able to use
1040 the value from the `id` field, because we haven’t saved the `id` value in a
1041 variable.
1042
1043 In the last arm where we’ve specified a variable without a range, we do have
1044 the value available to use in the arm’s code in a variable named `id` because
1045 we’ve used the struct field shorthand syntax. We haven’t applied any test to
1046 the value in the `id` field in this arm, though, like the first two arms did:
1047 any value would match this pattern.
1048
1049 Using `@` lets us test a value and save it in a variable within one pattern.
1050
1051 ## Summary
1052
1053 Patterns are a useful feature of Rust that help distinguish between different
1054 kinds of data. When used in `match` statements, Rust makes sure your patterns
1055 cover every possible value, or your program will not compile. Patterns in `let`
1056 statements and function parameters make those constructs more powerful,
1057 enabling the destructuring of values into smaller parts at the same time as
1058 assigning to variables. We can create simple or complex patterns to suit our
1059 needs.
1060
1061 Now, for the penultimate chapter of the book, let’s take a look at some
1062 advanced parts of a variety of Rust’s features.