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
9 As you saw in Chapter 6, you can match patterns against literals directly. The
10 following code gives some examples:
13 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs:here}}
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
20 ### Matching Named Variables
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.
33 <span class="filename">Filename: src/main.rs</span>
36 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-11/src/main.rs:here}}
39 <span class="caption">Listing 18-11: A `match` expression with an arm that
40 introduces a shadowed variable `y`</span>
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
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`.
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
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`.
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)<!--
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
79 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs:here}}
82 This code prints `one or two`.
84 ### Matching Ranges of Values with `..=`
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
91 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs:here}}
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!
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.
104 Here is an example using ranges of `char` values:
107 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs:here}}
110 Rust can tell that `c` is within the first pattern’s range and prints `early
113 ### Destructuring to Break Apart Values
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.
118 #### Destructuring Structs
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.
123 <span class="filename">Filename: src/main.rs</span>
126 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-12/src/main.rs}}
129 <span class="caption">Listing 18-12: Destructuring a struct’s fields into
130 separate variables</span>
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.
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`.
146 <span class="filename">Filename: src/main.rs</span>
149 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-13/src/main.rs}}
152 <span class="caption">Listing 18-13: Destructuring struct fields using struct
153 field shorthand</span>
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.
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.
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.
168 <span class="filename">Filename: src/main.rs</span>
171 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-14/src/main.rs:here}}
174 <span class="caption">Listing 18-14: Destructuring and matching literal values
175 in one pattern</span>
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.
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.
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`.
189 #### Destructuring Enums
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.
198 <span class="filename">Filename: src/main.rs</span>
201 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-15/src/main.rs}}
204 <span class="caption">Listing 18-15: Destructuring enum variants that hold
205 different kinds of values</span>
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.
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.
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.
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
226 #### Destructuring Nested Structs and Enums
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!
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.
235 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-16/src/main.rs}}
238 <span class="caption">Listing 18-16: Matching on nested enums</span>
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.
247 #### Destructuring Structs and Tuples
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:
254 {{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs:here}}
257 This code lets us break complex types into their component parts so we can use
258 the values we’re interested in separately.
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.
263 ### Ignoring Values in a Pattern
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.
273 #### Ignoring an Entire Value with `_`
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.
280 <span class="filename">Filename: src/main.rs</span>
283 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-17/src/main.rs}}
286 <span class="caption">Listing 18-17: Using `_` in a function signature</span>
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`.
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
299 #### Ignoring Parts of a Value with a Nested `_`
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.
309 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-18/src/main.rs:here}}
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
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
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`.
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.
332 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-19/src/main.rs:here}}
335 <span class="caption">Listing 18-19: Ignoring multiple parts of a tuple</span>
337 This code will print `Some numbers: 2, 8, 32`, and the values 4 and 16 will be
340 #### Ignoring an Unused Variable by Starting Its Name with `_`
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.
350 <span class="filename">Filename: src/main.rs</span>
353 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-20/src/main.rs}}
356 <span class="caption">Listing 18-20: Starting a variable name with an
357 underscore to avoid getting unused variable warnings</span>
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.
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.
367 ```rust,ignore,does_not_compile
368 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-21/src/main.rs:here}}
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>
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 `_`.
380 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-22/src/main.rs:here}}
383 <span class="caption">Listing 18-22: Using an underscore does not bind the
386 This code works just fine because we never bind `s` to anything; it isn’t moved.
388 #### Ignoring Remaining Parts of a Value with `..`
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.
399 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-23/src/main.rs:here}}
402 <span class="caption">Listing 18-23: Ignoring all fields of a `Point` except
403 for `x` by using `..`</span>
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
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.
413 <span class="filename">Filename: src/main.rs</span>
416 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-24/src/main.rs}}
419 <span class="caption">Listing 18-24: Matching only the first and last values in
420 a tuple and ignoring all other values</span>
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.
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
430 <span class="filename">Filename: src/main.rs</span>
432 ```rust,ignore,does_not_compile
433 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-25/src/main.rs}}
436 <span class="caption">Listing 18-25: An attempt to use `..` in an ambiguous
439 When we compile this example, we get this error:
442 {{#include ../listings/ch18-patterns-and-matching/listing-18-25/output.txt}}
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.
453 ### Extra Conditionals with Match Guards
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.
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
465 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-26/src/main.rs:here}}
468 <span class="caption">Listing 18-26: Adding a match guard to a pattern</span>
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.
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.
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.
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
490 <span class="filename">Filename: src/main.rs</span>
493 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-27/src/main.rs}}
496 <span class="caption">Listing 18-27: Using a match guard to test for equality
497 with an outer variable</span>
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`.
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
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
519 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-28/src/main.rs:here}}
522 <span class="caption">Listing 18-28: Combining multiple patterns with a match
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
535 (4 | 5 | 6) if y => ...
541 4 | 5 | (6 if y) => ...
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
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
560 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-29/src/main.rs:here}}
563 <span class="caption">Listing 18-29: Using `@` to bind to a value in a pattern
564 while also testing it</span>
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.
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.
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.
583 Using `@` lets us test a value and save it in a variable within one pattern.
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.
594 Next, for the penultimate chapter of the book, we’ll look at some advanced
595 aspects of a variety of Rust’s features.