Skip to content

Commit c222aee

Browse files
committed
trpl/enums: Rewrite
1 parent 0e4629c commit c222aee

File tree

2 files changed

+56
-47
lines changed

2 files changed

+56
-47
lines changed

src/doc/trpl/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
* [References and Borrowing](references-and-borrowing.md)
2828
* [Lifetimes](lifetimes.md)
2929
* [Mutability](mutability.md)
30-
* [Enums](enums.md)
3130
* [Match](match.md)
3231
* [Structs](structs.md)
32+
* [Enums](enums.md)
3333
* [Patterns](patterns.md)
3434
* [Method Syntax](method-syntax.md)
3535
* [Vectors](vectors.md)

src/doc/trpl/enums.md

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,76 @@
22

33
Rust has a ‘sum type’, an `enum`. Enums are an incredibly useful feature of
44
Rust, and are used throughout the standard library. An `enum` is a type which
5-
relates a set of alternates to a specific name. For example, below we define
6-
`Character` to be either a `Digit` or something else.
5+
relates a set of alternates to a specific name. Each variant of an
6+
`enum` is defined like a struct, and can hold any data (or no data, like
7+
a unit-like struct).
78

89
```rust
9-
enum Character {
10-
Digit(i32),
11-
Other,
10+
enum Message {
11+
Quit,
12+
ChangeColor(i32, i32, i32),
13+
Move { x: i32, y: i32 },
14+
Write(String),
1215
}
1316
```
1417

15-
Most types are allowed as the variant components of an `enum`. Here are some
16-
examples:
18+
We use the `::` syntax to use the name of each variant: they’re scoped by the name
19+
of the `enum` itself. This allows both of these to work:
1720

1821
```rust
19-
struct Empty;
20-
struct Color(i32, i32, i32);
21-
struct Length(i32);
22-
struct Stats { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
23-
struct HeightDatabase(Vec<i32>);
24-
```
25-
26-
You see that, depending on its type, an `enum` variant may or may not hold data.
27-
In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
28-
value, where `Other` is only a name. However, the fact that they represent
29-
distinct categories of `Character` is a very useful property.
30-
31-
The variants of an `enum` by default are not comparable with equality operators
32-
(`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not support other
33-
binary operations such as `*` and `+`. As such, the following code is invalid
34-
for the example `Character` type:
22+
# enum Message {
23+
# Move { x: i32, y: i32 },
24+
# }
25+
let x = Message::Move { x: 3, y: 4 };
3526

36-
```rust,ignore
37-
// These assignments both succeed
38-
let ten = Character::Digit(10);
39-
let four = Character::Digit(4);
40-
41-
// Error: `*` is not implemented for type `Character`
42-
let forty = ten * four;
43-
44-
// Error: `<=` is not implemented for type `Character`
45-
let four_is_smaller = four <= ten;
27+
enum BoardGame {
28+
Move { squares: i32 },
29+
Pass,
30+
}
4631

47-
// Error: `==` is not implemented for type `Character`
48-
let four_equals_ten = four == ten;
32+
let y = BoardGame::Move { squares: 1 };
4933
```
5034

51-
We use the `::` syntax to use the name of each variant: They’re scoped by the name
52-
of the `enum` itself. This allows both of these to work:
35+
Both variants are named `Move`, but since they’re scoped to the name of
36+
the enum, they can both be used without conflict.
37+
38+
Rust’s enums are similar to C’s enums, but they can also hold data. In
39+
this respect, they are also somewhat similar to C unions. Unlike C
40+
unions, however, Rust enums carry information about which variant a
41+
particular instance of the union is. (This is sometimes referred to as a
42+
‘tagged union’ in other languages.) The compiler uses this information
43+
to enforce that you’re accessing the data in the enum safely:
5344

5445
```rust,ignore
55-
Character::Digit(10);
56-
Hand::Digit;
46+
fn process_color_change(msg: Message) {
47+
let Message::ChangeColor(r, g, b) = msg; // compile-time error
48+
}
5749
```
5850

59-
Both variants are named `Digit`, but since they’re scoped to the `enum` name,
51+
You can use [matches][match] to process all possible variants of a union (or
52+
the [`if let`][if-let] statement, which we’ll see later, to match on a
53+
single one):
6054

61-
Not supporting these operations may seem rather limiting, but it’s a limitation
62-
which we can overcome. There are two ways: by implementing equality ourselves,
63-
or by pattern matching variants with [`match`][match] expressions, which you’ll
64-
learn in the next section. We don’t know enough about Rust to implement
65-
equality yet, but we’ll find out in the [`traits`][traits] section.
55+
```rust
56+
# enum Message {
57+
# Quit,
58+
# ChangeColor(i32, i32, i32),
59+
# Move { x: i32, y: i32 },
60+
# Write(String),
61+
# }
62+
fn quit() { /* ... */ }
63+
fn change_color(r: i32, g: i32, b: i32) { /* ... */ }
64+
fn move_cursor(x: i32, y: i32) { /* ... */ }
65+
66+
fn process_message(msg: Message) {
67+
match msg {
68+
Message::Quit => quit(),
69+
Message::ChangeColor(r, g, b) => change_color(r, g, b),
70+
Message::Move { x: x, y: y } => move_cursor(x, y),
71+
Message::Write(s) => println!("{}", s),
72+
}
73+
}
74+
```
6675

6776
[match]: match.html
68-
[traits]: traits.html
77+
[if-let]: if-let.html

0 commit comments

Comments
 (0)