about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/trpl/match.md140
1 files changed, 23 insertions, 117 deletions
diff --git a/src/doc/trpl/match.md b/src/doc/trpl/match.md
index 73bc775a1b2..33d603f326a 100644
--- a/src/doc/trpl/match.md
+++ b/src/doc/trpl/match.md
@@ -1,13 +1,13 @@
 % Match
 
-Often, a simple `if`/`else` isn't enough, because you have more than two
+Often, a simple `if`/`else` isn’t enough, because you have more than two
 possible options. Also, `else` conditions can get incredibly complicated, so
-what's the solution?
+what’s the solution?
 
 Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
 groupings with something more powerful. Check it out:
 
-```{rust}
+```rust
 let x = 5;
 
 match x {
@@ -21,11 +21,14 @@ match x {
 ```
 
 `match` takes an expression and then branches based on its value. Each *arm* of
-the branch is of the form `val => expression`. When the value matches, that arm's
-expression will be evaluated. It's called `match` because of the term 'pattern
-matching', which `match` is an implementation of.
+the branch is of the form `val => expression`. When the value matches, that arm’s
+expression will be evaluated. It’s called `match` because of the term ‘pattern
+matching’, which `match` is an implementation of. There’s an [entire section on
+patterns][patterns] coming up next, that covers all the options that fit here.
 
-So what's the big advantage here? Well, there are a few. First of all, `match`
+[patterns]: patterns.html
+
+So what’s the big advantage here? Well, there are a few. First of all, `match`
 enforces *exhaustiveness checking*. Do you see that last arm, the one with the
 underscore (`_`)? If we remove that arm, Rust will give us an error:
 
@@ -36,121 +39,24 @@ error: non-exhaustive patterns: `_` not covered
 In other words, Rust is trying to tell us we forgot a value. Because `x` is an
 integer, Rust knows that it can have a number of different values – for example,
 `6`. Without the `_`, however, there is no arm that could match, and so Rust refuses
-to compile. `_` acts like a *catch-all arm*. If none of the other arms match,
+to compile. `_` acts like a ‘catch-all arm’. If none of the other arms match,
 the arm with `_` will, and since we have this catch-all arm, we now have an arm
 for every possible value of `x`, and so our program will compile successfully.
 
-`match` statements also destructure enums, as well. Remember this code from the
-section on enums?
-
-```{rust}
-use std::cmp::Ordering;
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
-
-    let ordering = cmp(x, y);
-
-    if ordering == Ordering::Less {
-        println!("less");
-    } else if ordering == Ordering::Greater {
-        println!("greater");
-    } else if ordering == Ordering::Equal {
-        println!("equal");
-    }
-}
-```
-
-We can re-write this as a `match`:
-
-```{rust}
-use std::cmp::Ordering;
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
-
-    match cmp(x, y) {
-        Ordering::Less => println!("less"),
-        Ordering::Greater => println!("greater"),
-        Ordering::Equal => println!("equal"),
-    }
-}
-```
-
-This version has way less noise, and it also checks exhaustively to make sure
-that we have covered all possible variants of `Ordering`. With our `if`/`else`
-version, if we had forgotten the `Greater` case, for example, our program would
-have happily compiled. If we forget in the `match`, it will not. Rust helps us
-make sure to cover all of our bases.
-
-`match` expressions also allow us to get the values contained in an `enum`
-(also known as destructuring) as follows:
-
-```{rust}
-enum OptionalInt {
-    Value(i32),
-    Missing,
-}
-
-fn main() {
-    let x = OptionalInt::Value(5);
-    let y = OptionalInt::Missing;
-
-    match x {
-        OptionalInt::Value(n) => println!("x is {}", n),
-        OptionalInt::Missing => println!("x is missing!"),
-    }
-
-    match y {
-        OptionalInt::Value(n) => println!("y is {}", n),
-        OptionalInt::Missing => println!("y is missing!"),
-    }
-}
-```
-
-That is how you can get and use the values contained in `enum`s.
-It can also allow us to handle errors or unexpected computations; for example, a
-function that is not guaranteed to be able to compute a result (an `i32` here)
-could return an `OptionalInt`, and we would handle that value with a `match`.
-As you can see, `enum` and `match` used together are quite useful!
-
 `match` is also an expression, which means we can use it on the right-hand
-side of a `let` binding or directly where an expression is used. We could
-also implement the previous example like this:
-
-```{rust}
-use std::cmp::Ordering;
+side of a `let` binding or directly where an expression is used:
 
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
+```rust
+let x = 5;
 
-    println!("{}", match cmp(x, y) {
-        Ordering::Less => "less",
-        Ordering::Greater => "greater",
-        Ordering::Equal => "equal",
-    });
-}
+let numer = match x {
+    1 => "one",
+    2 => "two",
+    3 => "three",
+    4 => "four",
+    5 => "five",
+    _ => "something else",
+};
 ```
 
-Sometimes, it's a nice pattern.
+Sometimes, it’s a nice way of converting things.