]> git.proxmox.com Git - rustc.git/blob - src/doc/book/src/ch18-02-refutability.md
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / book / src / ch18-02-refutability.md
1 ## Refutability: Whether a Pattern Might Fail to Match
2
3 Patterns come in two forms: refutable and irrefutable. Patterns that will match
4 for any possible value passed are *irrefutable*. An example would be `x` in the
5 statement `let x = 5;` because `x` matches anything and therefore cannot fail
6 to match. Patterns that can fail to match for some possible value are
7 *refutable*. An example would be `Some(x)` in the expression `if let Some(x) =
8 a_value` because if the value in the `a_value` variable is `None` rather than
9 `Some`, the `Some(x)` pattern will not match.
10
11 Function parameters, `let` statements, and `for` loops can only accept
12 irrefutable patterns, because the program cannot do anything meaningful when
13 values don’t match. The `if let` and `while let` expressions accept
14 refutable and irrefutable patterns, but the compiler warns against
15 irrefutable patterns because by definition they’re intended to handle possible
16 failure: the functionality of a conditional is in its ability to perform
17 differently depending on success or failure.
18
19 In general, you shouldn’t have to worry about the distinction between refutable
20 and irrefutable patterns; however, you do need to be familiar with the concept
21 of refutability so you can respond when you see it in an error message. In
22 those cases, you’ll need to change either the pattern or the construct you’re
23 using the pattern with, depending on the intended behavior of the code.
24
25 Let’s look at an example of what happens when we try to use a refutable pattern
26 where Rust requires an irrefutable pattern and vice versa. Listing 18-8 shows a
27 `let` statement, but for the pattern we’ve specified `Some(x)`, a refutable
28 pattern. As you might expect, this code will not compile.
29
30 ```rust,ignore,does_not_compile
31 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-08/src/main.rs:here}}
32 ```
33
34 <span class="caption">Listing 18-8: Attempting to use a refutable pattern with
35 `let`</span>
36
37 If `some_option_value` was a `None` value, it would fail to match the pattern
38 `Some(x)`, meaning the pattern is refutable. However, the `let` statement can
39 only accept an irrefutable pattern because there is nothing valid the code can
40 do with a `None` value. At compile time, Rust will complain that we’ve tried to
41 use a refutable pattern where an irrefutable pattern is required:
42
43 ```console
44 {{#include ../listings/ch18-patterns-and-matching/listing-18-08/output.txt}}
45 ```
46
47 Because we didn’t cover (and couldn’t cover!) every valid value with the
48 pattern `Some(x)`, Rust rightfully produces a compiler error.
49
50 If we have a refutable pattern where an irrefutable pattern is needed, we can
51 fix it by changing the code that uses the pattern: instead of using `let`, we
52 can use `if let`. Then if the pattern doesn’t match, the code will just skip
53 the code in the curly brackets, giving it a way to continue validly. Listing
54 18-9 shows how to fix the code in Listing 18-8.
55
56 ```rust
57 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-09/src/main.rs:here}}
58 ```
59
60 <span class="caption">Listing 18-9: Using `if let` and a block with refutable
61 patterns instead of `let`</span>
62
63 We’ve given the code an out! This code is perfectly valid, although it means we
64 cannot use an irrefutable pattern without receiving an error. If we give `if
65 let` a pattern that will always match, such as `x`, as shown in Listing 18-10,
66 the compiler will give a warning.
67
68 ```rust
69 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-10/src/main.rs:here}}
70 ```
71
72 <span class="caption">Listing 18-10: Attempting to use an irrefutable pattern
73 with `if let`</span>
74
75 Rust complains that it doesn’t make sense to use `if let` with an irrefutable
76 pattern:
77
78 ```console
79 {{#include ../listings/ch18-patterns-and-matching/listing-18-10/output.txt}}
80 ```
81
82 For this reason, match arms must use refutable patterns, except for the last
83 arm, which should match any remaining values with an irrefutable pattern. Rust
84 allows us to use an irrefutable pattern in a `match` with only one arm, but
85 this syntax isn’t particularly useful and could be replaced with a simpler
86 `let` statement.
87
88 Now that you know where to use patterns and the difference between refutable
89 and irrefutable patterns, let’s cover all the syntax we can use to create
90 patterns.