]> git.proxmox.com Git - rustc.git/blob - src/doc/book/src/ch18-03-pattern-syntax.md
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / src / doc / book / src / ch18-03-pattern-syntax.md
1 ## Pattern Syntax
2
3 Throughout the book, you’ve seen examples of many kinds of patterns. In this
4 section, we gather all the syntax valid in patterns and discuss why you might
5 want to use each one.
6
7 ### Matching Literals
8
9 As you saw in Chapter 6, you can match patterns against literals directly. The
10 following code gives some examples:
11
12 ```rust
13 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs:here}}
14 ```
15
16 This code prints `one` because the value in `x` is 1. This syntax is useful
17 when you want your code to take an action if it gets a particular concrete
18 value.
19
20 ### Matching Named Variables
21
22 Named variables are irrefutable patterns that match any value, and we’ve used
23 them many times in the book. However, there is a complication when you use
24 named variables in `match` expressions. Because `match` starts a new scope,
25 variables declared as part of a pattern inside the `match` expression will
26 shadow those with the same name outside the `match` construct, as is the case
27 with all variables. In Listing 18-11, we declare a variable named `x` with the
28 value `Some(5)` and a variable `y` with the value `10`. We then create a
29 `match` expression on the value `x`. Look at the patterns in the match arms and
30 `println!` at the end, and try to figure out what the code will print before
31 running this code or reading further.
32
33 <span class="filename">Filename: src/main.rs</span>
34
35 ```rust
36 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-11/src/main.rs:here}}
37 ```
38
39 <span class="caption">Listing 18-11: A `match` expression with an arm that
40 introduces a shadowed variable `y`</span>
41
42 Let’s walk through what happens when the `match` expression runs. The pattern
43 in the first match arm doesn’t match the defined value of `x`, so the code
44 continues.
45
46 The pattern in the second match arm introduces a new variable named `y` that
47 will match any value inside a `Some` value. Because we’re in a new scope inside
48 the `match` expression, this is a new `y` variable, not the `y` we declared at
49 the beginning with the value 10. This new `y` binding will match any value
50 inside a `Some`, which is what we have in `x`. Therefore, this new `y` binds to
51 the inner value of the `Some` in `x`. That value is `5`, so the expression for
52 that arm executes and prints `Matched, y = 5`.
53
54 If `x` had been a `None` value instead of `Some(5)`, the patterns in the first
55 two arms wouldn’t have matched, so the value would have matched to the
56 underscore. We didn’t introduce the `x` variable in the pattern of the
57 underscore arm, so the `x` in the expression is still the outer `x` that hasn’t
58 been shadowed. In this hypothetical case, the `match` would print `Default
59 case, x = None`.
60
61 When the `match` expression is done, its scope ends, and so does the scope of
62 the inner `y`. The last `println!` produces `at the end: x = Some(5), y = 10`.
63
64 To create a `match` expression that compares the values of the outer `x` and
65 `y`, rather than introducing a shadowed variable, we would need to use a match
66 guard conditional instead. We’ll talk about match guards later in the [“Extra
67 Conditionals with Match Guards”](#extra-conditionals-with-match-guards)<!--
68 ignore --> section.
69
70 ### Multiple Patterns
71
72 In `match` expressions, you can match multiple patterns using the `|` syntax,
73 which means *or*. For example, the following code matches the value of `x`
74 against the match arms, the first of which has an *or* option, meaning if the
75 value of `x` matches either of the values in that arm, that arm’s code will
76 run:
77
78 ```rust
79 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs:here}}
80 ```
81
82 This code prints `one or two`.
83
84 ### Matching Ranges of Values with `..=`
85
86 The `..=` syntax allows us to match to an inclusive range of values. In the
87 following code, when a pattern matches any of the values within the range, that
88 arm will execute:
89
90 ```rust
91 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs:here}}
92 ```
93
94 If `x` is 1, 2, 3, 4, or 5, the first arm will match. This syntax is more
95 convenient than using the `|` operator to express the same idea; instead of
96 `1..=5`, we would have to specify `1 | 2 | 3 | 4 | 5` if we used `|`.
97 Specifying a range is much shorter, especially if we want to match, say, any
98 number between 1 and 1,000!
99
100 Ranges are only allowed with numeric values or `char` values, because the
101 compiler checks that the range isn’t empty at compile time. The only types for
102 which Rust can tell if a range is empty or not are `char` and numeric values.
103
104 Here is an example using ranges of `char` values:
105
106 ```rust
107 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs:here}}
108 ```
109
110 Rust can tell that `c` is within the first pattern’s range and prints `early
111 ASCII letter`.
112
113 ### Destructuring to Break Apart Values
114
115 We can also use patterns to destructure structs, enums, tuples, and references
116 to use different parts of these values. Let’s walk through each value.
117
118 #### Destructuring Structs
119
120 Listing 18-12 shows a `Point` struct with two fields, `x` and `y`, that we can
121 break apart using a pattern with a `let` statement.
122
123 <span class="filename">Filename: src/main.rs</span>
124
125 ```rust
126 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-12/src/main.rs}}
127 ```
128
129 <span class="caption">Listing 18-12: Destructuring a struct’s fields into
130 separate variables</span>
131
132 This code creates the variables `a` and `b` that match the values of the `x`
133 and `y` fields of the `p` struct. This example shows that the names of the
134 variables in the pattern don’t have to match the field names of the struct. But
135 it’s common to want the variable names to match the field names to make it
136 easier to remember which variables came from which fields.
137
138 Because having variable names match the fields is common and because writing
139 `let Point { x: x, y: y } = p;` contains a lot of duplication, there is a
140 shorthand for patterns that match struct fields: you only need to list the name
141 of the struct field, and the variables created from the pattern will have the
142 same names. Listing 18-13 shows code that behaves in the same way as the code
143 in Listing 18-12, but the variables created in the `let` pattern are `x` and
144 `y` instead of `a` and `b`.
145
146 <span class="filename">Filename: src/main.rs</span>
147
148 ```rust
149 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-13/src/main.rs}}
150 ```
151
152 <span class="caption">Listing 18-13: Destructuring struct fields using struct
153 field shorthand</span>
154
155 This code creates the variables `x` and `y` that match the `x` and `y` fields
156 of the `p` variable. The outcome is that the variables `x` and `y` contain the
157 values from the `p` struct.
158
159 We can also destructure with literal values as part of the struct pattern
160 rather than creating variables for all the fields. Doing so allows us to test
161 some of the fields for particular values while creating variables to
162 destructure the other fields.
163
164 Listing 18-14 shows a `match` expression that separates `Point` values into
165 three cases: points that lie directly on the `x` axis (which is true when `y =
166 0`), on the `y` axis (`x = 0`), or neither.
167
168 <span class="filename">Filename: src/main.rs</span>
169
170 ```rust
171 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-14/src/main.rs:here}}
172 ```
173
174 <span class="caption">Listing 18-14: Destructuring and matching literal values
175 in one pattern</span>
176
177 The first arm will match any point that lies on the `x` axis by specifying that
178 the `y` field matches if its value matches the literal `0`. The pattern still
179 creates an `x` variable that we can use in the code for this arm.
180
181 Similarly, the second arm matches any point on the `y` axis by specifying that
182 the `x` field matches if its value is `0` and creates a variable `y` for the
183 value of the `y` field. The third arm doesn’t specify any literals, so it
184 matches any other `Point` and creates variables for both the `x` and `y` fields.
185
186 In this example, the value `p` matches the second arm by virtue of `x`
187 containing a 0, so this code will print `On the y axis at 7`.
188
189 #### Destructuring Enums
190
191 We’ve destructured enums earlier in this book, for example, when we
192 destructured `Option<i32>` in Listing 6-5 in Chapter 6. One detail we haven’t
193 mentioned explicitly is that the pattern to destructure an enum should
194 correspond to the way the data stored within the enum is defined. As an
195 example, in Listing 18-15 we use the `Message` enum from Listing 6-2 and write
196 a `match` with patterns that will destructure each inner value.
197
198 <span class="filename">Filename: src/main.rs</span>
199
200 ```rust
201 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-15/src/main.rs}}
202 ```
203
204 <span class="caption">Listing 18-15: Destructuring enum variants that hold
205 different kinds of values</span>
206
207 This code will print `Change the color to red 0, green 160, and blue 255`. Try
208 changing the value of `msg` to see the code from the other arms run.
209
210 For enum variants without any data, like `Message::Quit`, we can’t destructure
211 the value any further. We can only match on the literal `Message::Quit` value,
212 and no variables are in that pattern.
213
214 For struct-like enum variants, such as `Message::Move`, we can use a pattern
215 similar to the pattern we specify to match structs. After the variant name, we
216 place curly brackets and then list the fields with variables so we break apart
217 the pieces to use in the code for this arm. Here we use the shorthand form as
218 we did in Listing 18-13.
219
220 For tuple-like enum variants, like `Message::Write` that holds a tuple with one
221 element and `Message::ChangeColor` that holds a tuple with three elements, the
222 pattern is similar to the pattern we specify to match tuples. The number of
223 variables in the pattern must match the number of elements in the variant we’re
224 matching.
225
226 #### Destructuring Nested Structs and Enums
227
228 Until now, all our examples have been matching structs or enums that were one
229 level deep. Matching can work on nested items too!
230
231 For example, we can refactor the code in Listing 18-15 to support RGB and HSV
232 colors in the `ChangeColor` message, as shown in Listing 18-16.
233
234 ```rust
235 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-16/src/main.rs}}
236 ```
237
238 <span class="caption">Listing 18-16: Matching on nested enums</span>
239
240 The pattern of the first arm in the `match` expression matches a
241 `Message::ChangeColor` enum variant that contains a `Color::Rgb` variant; then
242 the pattern binds to the three inner `i32` values. The pattern of the second
243 arm also matches a `Message::ChangeColor` enum variant, but the inner enum
244 matches the `Color::Hsv` variant instead. We can specify these complex
245 conditions in one `match` expression, even though two enums are involved.
246
247 #### Destructuring Structs and Tuples
248
249 We can mix, match, and nest destructuring patterns in even more complex ways.
250 The following example shows a complicated destructure where we nest structs and
251 tuples inside a tuple and destructure all the primitive values out:
252
253 ```rust
254 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs:here}}
255 ```
256
257 This code lets us break complex types into their component parts so we can use
258 the values we’re interested in separately.
259
260 Destructuring with patterns is a convenient way to use pieces of values, such
261 as the value from each field in a struct, separately from each other.
262
263 ### Ignoring Values in a Pattern
264
265 You’ve seen that it’s sometimes useful to ignore values in a pattern, such as
266 in the last arm of a `match`, to get a catchall that doesn’t actually do
267 anything but does account for all remaining possible values. There are a few
268 ways to ignore entire values or parts of values in a pattern: using the `_`
269 pattern (which you’ve seen), using the `_` pattern within another pattern,
270 using a name that starts with an underscore, or using `..` to ignore remaining
271 parts of a value. Let’s explore how and why to use each of these patterns.
272
273 #### Ignoring an Entire Value with `_`
274
275 We’ve used the underscore (`_`) as a wildcard pattern that will match any value
276 but not bind to the value. Although the underscore `_` pattern is especially
277 useful as the last arm in a `match` expression, we can use it in any pattern,
278 including function parameters, as shown in Listing 18-17.
279
280 <span class="filename">Filename: src/main.rs</span>
281
282 ```rust
283 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-17/src/main.rs}}
284 ```
285
286 <span class="caption">Listing 18-17: Using `_` in a function signature</span>
287
288 This code will completely ignore the value passed as the first argument, `3`,
289 and will print `This code only uses the y parameter: 4`.
290
291 In most cases when you no longer need a particular function parameter, you
292 would change the signature so it doesn’t include the unused parameter. Ignoring
293 a function parameter can be especially useful in some cases, for example, when
294 implementing a trait when you need a certain type signature but the function
295 body in your implementation doesn’t need one of the parameters. The compiler
296 will then not warn about unused function parameters, as it would if you used a
297 name instead.
298
299 #### Ignoring Parts of a Value with a Nested `_`
300
301 We can also use `_` inside another pattern to ignore just part of a value, for
302 example, when we want to test for only part of a value but have no use for the
303 other parts in the corresponding code we want to run. Listing 18-18 shows code
304 responsible for managing a setting’s value. The business requirements are that
305 the user should not be allowed to overwrite an existing customization of a
306 setting but can unset the setting and give it a value if it is currently unset.
307
308 ```rust
309 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-18/src/main.rs:here}}
310 ```
311
312 <span class="caption">Listing 18-18: Using an underscore within patterns that
313 match `Some` variants when we don’t need to use the value inside the
314 `Some`</span>
315
316 This code will print `Can't overwrite an existing customized value` and then
317 `setting is Some(5)`. In the first match arm, we don’t need to match on or use
318 the values inside either `Some` variant, but we do need to test for the case
319 when `setting_value` and `new_setting_value` are the `Some` variant. In that
320 case, we print why we’re not changing `setting_value`, and it doesn’t get
321 changed.
322
323 In all other cases (if either `setting_value` or `new_setting_value` are
324 `None`) expressed by the `_` pattern in the second arm, we want to allow
325 `new_setting_value` to become `setting_value`.
326
327 We can also use underscores in multiple places within one pattern to ignore
328 particular values. Listing 18-19 shows an example of ignoring the second and
329 fourth values in a tuple of five items.
330
331 ```rust
332 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-19/src/main.rs:here}}
333 ```
334
335 <span class="caption">Listing 18-19: Ignoring multiple parts of a tuple</span>
336
337 This code will print `Some numbers: 2, 8, 32`, and the values 4 and 16 will be
338 ignored.
339
340 #### Ignoring an Unused Variable by Starting Its Name with `_`
341
342 If you create a variable but don’t use it anywhere, Rust will usually issue a
343 warning because that could be a bug. But sometimes it’s useful to create a
344 variable you won’t use yet, such as when you’re prototyping or just starting a
345 project. In this situation, you can tell Rust not to warn you about the unused
346 variable by starting the name of the variable with an underscore. In Listing
347 18-20, we create two unused variables, but when we run this code, we should
348 only get a warning about one of them.
349
350 <span class="filename">Filename: src/main.rs</span>
351
352 ```rust
353 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-20/src/main.rs}}
354 ```
355
356 <span class="caption">Listing 18-20: Starting a variable name with an
357 underscore to avoid getting unused variable warnings</span>
358
359 Here we get a warning about not using the variable `y`, but we don’t get a
360 warning about not using the variable preceded by the underscore.
361
362 Note that there is a subtle difference between using only `_` and using a name
363 that starts with an underscore. The syntax `_x` still binds the value to the
364 variable, whereas `_` doesn’t bind at all. To show a case where this
365 distinction matters, Listing 18-21 will provide us with an error.
366
367 ```rust,ignore,does_not_compile
368 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-21/src/main.rs:here}}
369 ```
370
371 <span class="caption">Listing 18-21: An unused variable starting with an
372 underscore still binds the value, which might take ownership of the value</span>
373
374 We’ll receive an error because the `s` value will still be moved into `_s`,
375 which prevents us from using `s` again. However, using the underscore by itself
376 doesn’t ever bind to the value. Listing 18-22 will compile without any errors
377 because `s` doesn’t get moved into `_`.
378
379 ```rust
380 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-22/src/main.rs:here}}
381 ```
382
383 <span class="caption">Listing 18-22: Using an underscore does not bind the
384 value</span>
385
386 This code works just fine because we never bind `s` to anything; it isn’t moved.
387
388 #### Ignoring Remaining Parts of a Value with `..`
389
390 With values that have many parts, we can use the `..` syntax to use only a few
391 parts and ignore the rest, avoiding the need to list underscores for each
392 ignored value. The `..` pattern ignores any parts of a value that we haven’t
393 explicitly matched in the rest of the pattern. In Listing 18-23, we have a
394 `Point` struct that holds a coordinate in three-dimensional space. In the
395 `match` expression, we want to operate only on the `x` coordinate and ignore
396 the values in the `y` and `z` fields.
397
398 ```rust
399 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-23/src/main.rs:here}}
400 ```
401
402 <span class="caption">Listing 18-23: Ignoring all fields of a `Point` except
403 for `x` by using `..`</span>
404
405 We list the `x` value and then just include the `..` pattern. This is quicker
406 than having to list `y: _` and `z: _`, particularly when we’re working with
407 structs that have lots of fields in situations where only one or two fields are
408 relevant.
409
410 The syntax `..` will expand to as many values as it needs to be. Listing 18-24
411 shows how to use `..` with a tuple.
412
413 <span class="filename">Filename: src/main.rs</span>
414
415 ```rust
416 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-24/src/main.rs}}
417 ```
418
419 <span class="caption">Listing 18-24: Matching only the first and last values in
420 a tuple and ignoring all other values</span>
421
422 In this code, the first and last value are matched with `first` and `last`. The
423 `..` will match and ignore everything in the middle.
424
425 However, using `..` must be unambiguous. If it is unclear which values are
426 intended for matching and which should be ignored, Rust will give us an error.
427 Listing 18-25 shows an example of using `..` ambiguously, so it will not
428 compile.
429
430 <span class="filename">Filename: src/main.rs</span>
431
432 ```rust,ignore,does_not_compile
433 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-25/src/main.rs}}
434 ```
435
436 <span class="caption">Listing 18-25: An attempt to use `..` in an ambiguous
437 way</span>
438
439 When we compile this example, we get this error:
440
441 ```console
442 {{#include ../listings/ch18-patterns-and-matching/listing-18-25/output.txt}}
443 ```
444
445 It’s impossible for Rust to determine how many values in the tuple to ignore
446 before matching a value with `second` and then how many further values to
447 ignore thereafter. This code could mean that we want to ignore `2`, bind
448 `second` to `4`, and then ignore `8`, `16`, and `32`; or that we want to ignore
449 `2` and `4`, bind `second` to `8`, and then ignore `16` and `32`; and so forth.
450 The variable name `second` doesn’t mean anything special to Rust, so we get a
451 compiler error because using `..` in two places like this is ambiguous.
452
453 ### Extra Conditionals with Match Guards
454
455 A *match guard* is an additional `if` condition specified after the pattern in
456 a `match` arm that must also match, along with the pattern matching, for that
457 arm to be chosen. Match guards are useful for expressing more complex ideas
458 than a pattern alone allows.
459
460 The condition can use variables created in the pattern. Listing 18-26 shows a
461 `match` where the first arm has the pattern `Some(x)` and also has a match
462 guard of `if x < 5`.
463
464 ```rust
465 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-26/src/main.rs:here}}
466 ```
467
468 <span class="caption">Listing 18-26: Adding a match guard to a pattern</span>
469
470 This example will print `less than five: 4`. When `num` is compared to the
471 pattern in the first arm, it matches, because `Some(4)` matches `Some(x)`. Then
472 the match guard checks whether the value in `x` is less than `5`, and because
473 it is, the first arm is selected.
474
475 If `num` had been `Some(10)` instead, the match guard in the first arm would
476 have been false because 10 is not less than 5. Rust would then go to the second
477 arm, which would match because the second arm doesn’t have a match guard and
478 therefore matches any `Some` variant.
479
480 There is no way to express the `if x < 5` condition within a pattern, so the
481 match guard gives us the ability to express this logic.
482
483 In Listing 18-11, we mentioned that we could use match guards to solve our
484 pattern-shadowing problem. Recall that a new variable was created inside the
485 pattern in the `match` expression instead of using the variable outside the
486 `match`. That new variable meant we couldn’t test against the value of the
487 outer variable. Listing 18-27 shows how we can use a match guard to fix this
488 problem.
489
490 <span class="filename">Filename: src/main.rs</span>
491
492 ```rust
493 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-27/src/main.rs}}
494 ```
495
496 <span class="caption">Listing 18-27: Using a match guard to test for equality
497 with an outer variable</span>
498
499 This code will now print `Default case, x = Some(5)`. The pattern in the second
500 match arm doesn’t introduce a new variable `y` that would shadow the outer `y`,
501 meaning we can use the outer `y` in the match guard. Instead of specifying the
502 pattern as `Some(y)`, which would have shadowed the outer `y`, we specify
503 `Some(n)`. This creates a new variable `n` that doesn’t shadow anything because
504 there is no `n` variable outside the `match`.
505
506 The match guard `if n == y` is not a pattern and therefore doesn’t introduce
507 new variables. This `y` *is* the outer `y` rather than a new shadowed `y`, and
508 we can look for a value that has the same value as the outer `y` by comparing
509 `n` to `y`.
510
511 You can also use the *or* operator `|` in a match guard to specify multiple
512 patterns; the match guard condition will apply to all the patterns. Listing
513 18-28 shows the precedence of combining a match guard with a pattern that uses
514 `|`. The important part of this example is that the `if y` match guard applies
515 to `4`, `5`, *and* `6`, even though it might look like `if y` only applies to
516 `6`.
517
518 ```rust
519 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-28/src/main.rs:here}}
520 ```
521
522 <span class="caption">Listing 18-28: Combining multiple patterns with a match
523 guard</span>
524
525 The match condition states that the arm only matches if the value of `x` is
526 equal to `4`, `5`, or `6` *and* if `y` is `true`. When this code runs, the
527 pattern of the first arm matches because `x` is `4`, but the match guard `if y`
528 is false, so the first arm is not chosen. The code moves on to the second arm,
529 which does match, and this program prints `no`. The reason is that the `if`
530 condition applies to the whole pattern `4 | 5 | 6`, not only to the last value
531 `6`. In other words, the precedence of a match guard in relation to a pattern
532 behaves like this:
533
534 ```text
535 (4 | 5 | 6) if y => ...
536 ```
537
538 rather than this:
539
540 ```text
541 4 | 5 | (6 if y) => ...
542 ```
543
544 After running the code, the precedence behavior is evident: if the match guard
545 were applied only to the final value in the list of values specified using the
546 `|` operator, the arm would have matched and the program would have printed
547 `yes`.
548
549 ### `@` Bindings
550
551 The *at* operator (`@`) lets us create a variable that holds a value at the
552 same time we’re testing that value to see whether it matches a pattern. Listing
553 18-29 shows an example where we want to test that a `Message::Hello` `id` field
554 is within the range `3..=7`. But we also want to bind the value to the variable
555 `id_variable` so we can use it in the code associated with the arm. We could
556 name this variable `id`, the same as the field, but for this example we’ll use
557 a different name.
558
559 ```rust
560 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-29/src/main.rs:here}}
561 ```
562
563 <span class="caption">Listing 18-29: Using `@` to bind to a value in a pattern
564 while also testing it</span>
565
566 This example will print `Found an id in range: 5`. By specifying `id_variable
567 @` before the range `3..=7`, we’re capturing whatever value matched the range
568 while also testing that the value matched the range pattern.
569
570 In the second arm, where we only have a range specified in the pattern, the code
571 associated with the arm doesn’t have a variable that contains the actual value
572 of the `id` field. The `id` field’s value could have been 10, 11, or 12, but
573 the code that goes with that pattern doesn’t know which it is. The pattern code
574 isn’t able to use the value from the `id` field, because we haven’t saved the
575 `id` value in a variable.
576
577 In the last arm, where we’ve specified a variable without a range, we do have
578 the value available to use in the arm’s code in a variable named `id`. The
579 reason is that we’ve used the struct field shorthand syntax. But we haven’t
580 applied any test to the value in the `id` field in this arm, as we did with the
581 first two arms: any value would match this pattern.
582
583 Using `@` lets us test a value and save it in a variable within one pattern.
584
585 ## Summary
586
587 Rust’s patterns are very useful in that they help distinguish between different
588 kinds of data. When used in `match` expressions, Rust ensures your patterns
589 cover every possible value, or your program won’t compile. Patterns in `let`
590 statements and function parameters make those constructs more useful, enabling
591 the destructuring of values into smaller parts at the same time as assigning to
592 variables. We can create simple or complex patterns to suit our needs.
593
594 Next, for the penultimate chapter of the book, we’ll look at some advanced
595 aspects of a variety of Rust’s features.