about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/guide.md71
1 files changed, 50 insertions, 21 deletions
diff --git a/src/doc/guide.md b/src/doc/guide.md
index f6aa04df1b9..750ac421e02 100644
--- a/src/doc/guide.md
+++ b/src/doc/guide.md
@@ -1124,21 +1124,6 @@ enum OptionalInt {
     Value(int),
     Missing,
 }
-
-fn main() {
-    let x = Value(5);
-    let y = Missing;
-
-    match x {
-        Value(n) => println!("x is {}", n),
-        Missing  => println!("x is missing!"),
-    }
-
-    match y {
-        Value(n) => println!("y is {}", n),
-        Missing  => println!("y is missing!"),
-    }
-}
 ```
 
 This enum represents an `int` that we may or may not have. In the `Missing`
@@ -1146,7 +1131,7 @@ case, we have no value, but in the `Value` case, we do. This enum is specific
 to `int`s, though. We can make it usable by any type, but we haven't quite
 gotten there yet!
 
-You can have any number of values in an enum:
+You can also have any number of values in an enum:
 
 ```{rust}
 enum OptionalColor {
@@ -1155,10 +1140,23 @@ enum OptionalColor {
 }
 ```
 
-Enums with values are quite useful, but as I mentioned, they're even more
-useful when they're generic across types. But before we get to generics, let's
-talk about how to fix these big `if`/`else` statements we've been writing. We'll
-do that with `match`.
+And you can also have something like this:
+
+```{rust}
+enum StringResult {
+    StringOK(String),
+    ErrorReason(String),
+}
+```
+Where a `StringResult` is either an `StringOK`, with the result of a computation, or an
+`ErrorReason` with a `String` explaining what caused the computation to fail. This kind of
+`enum`s are actually very useful and are even part of the standard library.
+
+As you can see `enum`s with values are quite a powerful tool for data representation,
+and can be even more useful when they're generic across types. But before we get to
+generics, let's talk about how to use them with pattern matching, a tool that will
+let us deconstruct this sum type (the type theory term for enums) in a very elegant
+way and avoid all these messy `if`/`else`s.
 
 # Match
 
@@ -1188,7 +1186,7 @@ expression will be evaluated. It's called `match` because of the term 'pattern
 matching,' which `match` is an implementation of.
 
 So what's the big advantage here? Well, there are a few. First of all, `match`
-does 'exhaustiveness checking.' Do you see that last arm, the one with the
+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:
 
 ```{ignore,notrust}
@@ -1255,6 +1253,37 @@ 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(int),
+    Missing,
+}
+
+fn main() {
+    let x = Value(5);
+    let y = Missing;
+
+    match x {
+        Value(n) => println!("x is {}", n),
+        Missing  => println!("x is missing!"),
+    }
+
+    match y {
+        Value(n) => println!("y is {}", n),
+        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 treat errors or unexpected computations, for example, a
+function that is not guaranteed to be able to compute a result (an `int` 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 line like this: