Skip to content

Commit 1b2ad78

Browse files
committed
auto merge of #18497 : gamazeps/rust/enumsmatch, r=steveklabnik
Closes #18169
2 parents 3a8f4ec + dc7c8da commit 1b2ad78

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

src/doc/guide.md

+50-21
Original file line numberDiff line numberDiff line change
@@ -1124,29 +1124,14 @@ enum OptionalInt {
11241124
Value(int),
11251125
Missing,
11261126
}
1127-
1128-
fn main() {
1129-
let x = Value(5);
1130-
let y = Missing;
1131-
1132-
match x {
1133-
Value(n) => println!("x is {}", n),
1134-
Missing => println!("x is missing!"),
1135-
}
1136-
1137-
match y {
1138-
Value(n) => println!("y is {}", n),
1139-
Missing => println!("y is missing!"),
1140-
}
1141-
}
11421127
```
11431128

11441129
This enum represents an `int` that we may or may not have. In the `Missing`
11451130
case, we have no value, but in the `Value` case, we do. This enum is specific
11461131
to `int`s, though. We can make it usable by any type, but we haven't quite
11471132
gotten there yet!
11481133

1149-
You can have any number of values in an enum:
1134+
You can also have any number of values in an enum:
11501135

11511136
```{rust}
11521137
enum OptionalColor {
@@ -1155,10 +1140,23 @@ enum OptionalColor {
11551140
}
11561141
```
11571142

1158-
Enums with values are quite useful, but as I mentioned, they're even more
1159-
useful when they're generic across types. But before we get to generics, let's
1160-
talk about how to fix these big `if`/`else` statements we've been writing. We'll
1161-
do that with `match`.
1143+
And you can also have something like this:
1144+
1145+
```{rust}
1146+
enum StringResult {
1147+
StringOK(String),
1148+
ErrorReason(String),
1149+
}
1150+
```
1151+
Where a `StringResult` is either an `StringOK`, with the result of a computation, or an
1152+
`ErrorReason` with a `String` explaining what caused the computation to fail. This kind of
1153+
`enum`s are actually very useful and are even part of the standard library.
1154+
1155+
As you can see `enum`s with values are quite a powerful tool for data representation,
1156+
and can be even more useful when they're generic across types. But before we get to
1157+
generics, let's talk about how to use them with pattern matching, a tool that will
1158+
let us deconstruct this sum type (the type theory term for enums) in a very elegant
1159+
way and avoid all these messy `if`/`else`s.
11621160

11631161
# Match
11641162

@@ -1188,7 +1186,7 @@ expression will be evaluated. It's called `match` because of the term 'pattern
11881186
matching,' which `match` is an implementation of.
11891187

11901188
So what's the big advantage here? Well, there are a few. First of all, `match`
1191-
does 'exhaustiveness checking.' Do you see that last arm, the one with the
1189+
enforces 'exhaustiveness checking.' Do you see that last arm, the one with the
11921190
underscore (`_`)? If we remove that arm, Rust will give us an error:
11931191

11941192
```{ignore,notrust}
@@ -1255,6 +1253,37 @@ version, if we had forgotten the `Greater` case, for example, our program would
12551253
have happily compiled. If we forget in the `match`, it will not. Rust helps us
12561254
make sure to cover all of our bases.
12571255

1256+
`match` expressions also allow us to get the values contained in an `enum`
1257+
(also known as destructuring) as follows:
1258+
1259+
```{rust}
1260+
enum OptionalInt {
1261+
Value(int),
1262+
Missing,
1263+
}
1264+
1265+
fn main() {
1266+
let x = Value(5);
1267+
let y = Missing;
1268+
1269+
match x {
1270+
Value(n) => println!("x is {}", n),
1271+
Missing => println!("x is missing!"),
1272+
}
1273+
1274+
match y {
1275+
Value(n) => println!("y is {}", n),
1276+
Missing => println!("y is missing!"),
1277+
}
1278+
}
1279+
```
1280+
1281+
That is how you can get and use the values contained in `enum`s.
1282+
It can also allow us to treat errors or unexpected computations, for example, a
1283+
function that is not guaranteed to be able to compute a result (an `int` here),
1284+
could return an `OptionalInt`, and we would handle that value with a `match`.
1285+
As you can see, `enum` and `match` used together are quite useful!
1286+
12581287
`match` is also an expression, which means we can use it on the right
12591288
hand side of a `let` binding or directly where an expression is
12601289
used. We could also implement the previous line like this:

0 commit comments

Comments
 (0)