]> git.proxmox.com Git - rustc.git/blobdiff - src/doc/book/src/ch18-01-all-the-places-for-patterns.md
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / book / src / ch18-01-all-the-places-for-patterns.md
index 42dddcaf1e486e264759a0e98e3558f6353b9d57..58f5af573bc505d6aef3e35af31543124aa1f8f1 100644 (file)
@@ -19,16 +19,29 @@ match VALUE {
 }
 ```
 
+For example, here's the `match` expression from Listing 6-5 that matches on an
+`Option<i32>` value in the variable `x`:
+
+```rust,ignore
+match x {
+    None => None,
+    Some(i) => Some(i + 1),
+}
+```
+
+The patterns in this `match` expression are the `None` and `Some(i)` on the
+left of each arrow.
+
 One requirement for `match` expressions is that they need to be *exhaustive* in
 the sense that all possibilities for the value in the `match` expression must
 be accounted for. One way to ensure you’ve covered every possibility is to have
 a catchall pattern for the last arm: for example, a variable name matching any
 value can never fail and thus covers every remaining case.
 
-A particular pattern `_` will match anything, but it never binds to a variable,
-so it’s often used in the last match arm. The `_` pattern can be useful when
-you want to ignore any value not specified, for example. We’ll cover the `_`
-pattern in more detail in the [“Ignoring Values in a
+The particular pattern `_` will match anything, but it never binds to a
+variable, so it’s often used in the last match arm. The `_` pattern can be
+useful when you want to ignore any value not specified, for example. We’ll
+cover the `_` pattern in more detail in the [“Ignoring Values in a
 Pattern”][ignoring-values-in-a-pattern]<!-- ignore --> section later in this
 chapter.
 
@@ -42,11 +55,11 @@ the pattern in the `if let` doesn’t match.
 Listing 18-1 shows that it’s also possible to mix and match `if let`, `else
 if`, and `else if let` expressions. Doing so gives us more flexibility than a
 `match` expression in which we can express only one value to compare with the
-patterns. Also, the conditions in a series of `if let`, `else if`, `else if
-let` arms aren’t required to relate to each other.
+patterns. Also, Rust doesn't require that the conditions in a series of `if
+let`, `else if`, `else if let` arms relate to each other.
 
-The code in Listing 18-1 shows a series of checks for several conditions that
-decide what the background color should be. For this example, we’ve created
+The code in Listing 18-1 determines what color to make your background based on
+a series of checks for several conditions. For this example, we’ve created
 variables with hardcoded values that a real program might receive from user
 input.
 
@@ -59,11 +72,12 @@ input.
 <span class="caption">Listing 18-1: Mixing `if let`, `else if`, `else if let`,
 and `else`</span>
 
-If the user specifies a favorite color, that color is the background color. If
-today is Tuesday, the background color is green. If the user specifies
-their age as a string and we can parse it as a number successfully, the color
-is either purple or orange depending on the value of the number. If none of
-these conditions apply, the background color is blue.
+If the user specifies a favorite color, that color is used as the background.
+If no favorite color is specified and today is Tuesday, the background color is
+green. Otherwise, if the user specifies their age as a string and we can parse
+it as a number successfully, the color is either purple or orange depending on
+the value of the number. If none of these conditions apply, the background
+color is blue.
 
 This conditional structure lets us support complex requirements. With the
 hardcoded values we have here, this example will print `Using purple as the
@@ -78,16 +92,16 @@ shadowed `age` we want to compare to 30 isn’t valid until the new scope starts
 with the curly bracket.
 
 The downside of using `if let` expressions is that the compiler doesn’t check
-exhaustiveness, whereas with `match` expressions it does. If we omitted the
+for exhaustiveness, whereas with `match` expressions it does. If we omitted the
 last `else` block and therefore missed handling some cases, the compiler would
 not alert us to the possible logic bug.
 
 ### `while let` Conditional Loops
 
 Similar in construction to `if let`, the `while let` conditional loop allows a
-`while` loop to run for as long as a pattern continues to match. The example in
-Listing 18-2 shows a `while let` loop that uses a vector as a stack and prints
-the values in the vector in the opposite order in which they were pushed.
+`while` loop to run for as long as a pattern continues to match. In Listing
+18-2 we code a `while let` loop that uses a vector as a stack and prints the
+values in the vector in the opposite order in which they were pushed.
 
 ```rust
 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-02/src/main.rs:here}}
@@ -104,13 +118,10 @@ use `while let` to pop every element off our stack.
 
 ### `for` Loops
 
-In Chapter 3, we mentioned that the `for` loop is the most common loop
-construction in Rust code, but we haven’t yet discussed the pattern that `for`
-takes. In a `for` loop, the pattern is the value that directly follows the
-keyword `for`, so in `for x in y` the `x` is the pattern.
-
-Listing 18-3 demonstrates how to use a pattern in a `for` loop to destructure,
-or break apart, a tuple as part of the `for` loop.
+In a `for` loop, the value that directly follows the keyword `for` is a
+pattern. For example, in `for x in y` the `x` is the pattern. Listing 18-3
+demonstrates how to use a pattern in a `for` loop to destructure, or break
+apart, a tuple as part of the `for` loop.
 
 ```rust
 {{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-03/src/main.rs:here}}
@@ -125,11 +136,11 @@ The code in Listing 18-3 will print the following:
 {{#include ../listings/ch18-patterns-and-matching/listing-18-03/output.txt}}
 ```
 
-We use the `enumerate` method to adapt an iterator to produce a value and that
-value’s index in the iterator, placed into a tuple. The first value produced is
-the tuple `(0, 'a')`. When this value is matched to the pattern `(index,
-value)`, `index` will be `0` and `value` will be `'a'`, printing the first line
-of the output.
+We adapt an iterator using the `enumerate` method so it produces a value and
+the index for that value, placed into a tuple. The first value produced is the
+tuple `(0, 'a')`. When this value is matched to the pattern `(index, value)`,
+`index` will be `0` and `value` will be `'a'`, printing the first line of the
+output.
 
 ### `let` Statements
 
@@ -142,9 +153,9 @@ variable assignment with `let`:
 let x = 5;
 ```
 
-Throughout this book, we’ve used `let` like this hundreds of times, and
-although you might not have realized it, you were using patterns! More
-formally, a `let` statement looks like this:
+Every time you've used a `let` statement like this you've been using patterns,
+although you might not have realized it! More formally, a `let` statement looks
+like this:
 
 ```text
 let PATTERN = EXPRESSION;
@@ -190,8 +201,8 @@ Attempting to compile this code results in this type error:
 {{#include ../listings/ch18-patterns-and-matching/listing-18-05/output.txt}}
 ```
 
-If we wanted to ignore one or more of the values in the tuple, we could use `_`
-or `..`, as you’ll see in the [“Ignoring Values in a
+To fix the error, we could ignore one or more of the values in the tuple using
+`_` or `..`, as you’ll see in the [“Ignoring Values in a
 Pattern”][ignoring-values-in-a-pattern]<!-- ignore --> section. If the problem
 is that we have too many variables in the pattern, the solution is to make the
 types match by removing variables so the number of variables equals the number