]> git.proxmox.com Git - rustc.git/blame - src/doc/trpl/enums.md
Imported Upstream version 1.5.0+dfsg1
[rustc.git] / src / doc / trpl / enums.md
CommitLineData
9346a6ac
AL
1% Enums
2
bd371182
AL
3An `enum` in Rust is a type that represents data that could be one of
4several possible variants:
9346a6ac
AL
5
6```rust
bd371182
AL
7enum Message {
8 Quit,
9 ChangeColor(i32, i32, i32),
10 Move { x: i32, y: i32 },
11 Write(String),
9346a6ac
AL
12}
13```
14
bd371182
AL
15Each variant can optionally have data associated with it. The syntax for
16defining variants resembles the syntaxes used to define structs: you can
17have variants with no data (like unit-like structs), variants with named
18data, and variants with unnamed data (like tuple structs). Unlike
19separate struct definitions, however, an `enum` is a single type. A
20value of the enum can match any of the variants. For this reason, an
21enum is sometimes called a ‘sum type’: the set of possible values of the
22enum is the sum of the sets of possible values for each variant.
9346a6ac 23
bd371182
AL
24We use the `::` syntax to use the name of each variant: they’re scoped by the name
25of the `enum` itself. This allows both of these to work:
9346a6ac 26
bd371182
AL
27```rust
28# enum Message {
29# Move { x: i32, y: i32 },
30# }
31let x: Message = Message::Move { x: 3, y: 4 };
32
33enum BoardGameTurn {
34 Move { squares: i32 },
35 Pass,
9346a6ac
AL
36}
37
bd371182 38let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };
9346a6ac
AL
39```
40
bd371182
AL
41Both variants are named `Move`, but since they’re scoped to the name of
42the enum, they can both be used without conflict.
9346a6ac 43
bd371182
AL
44A value of an enum type contains information about which variant it is,
45in addition to any data associated with that variant. This is sometimes
46referred to as a ‘tagged union’, since the data includes a ‘tag’
47indicating what type it is. The compiler uses this information to
48enforce that you’re accessing the data in the enum safely. For instance,
49you can’t simply try to destructure a value as if it were one of the
50possible variants:
9346a6ac 51
bd371182
AL
52```rust,ignore
53fn process_color_change(msg: Message) {
54 let Message::ChangeColor(r, g, b) = msg; // compile-time error
9346a6ac
AL
55}
56```
57
bd371182
AL
58Not supporting these operations may seem rather limiting, but it’s a limitation
59which we can overcome. There are two ways: by implementing equality ourselves,
60or by pattern matching variants with [`match`][match] expressions, which you’ll
61learn in the next section. We don’t know enough about Rust to implement
62equality yet, but we’ll find out in the [`traits`][traits] section.
9346a6ac 63
bd371182
AL
64[match]: match.html
65[if-let]: if-let.html
d9579d0f 66[traits]: traits.html
62682a34
SL
67
68# Constructors as functions
69
70An enum’s constructors can also be used like functions. For example:
71
72```rust
73# enum Message {
74# Write(String),
75# }
76let m = Message::Write("Hello, world".to_string());
77```
78
79Is the same as
80
81```rust
82# enum Message {
83# Write(String),
84# }
85fn foo(x: String) -> Message {
86 Message::Write(x)
87}
88
89let x = foo("Hello, world".to_string());
90```
91
92This is not immediately useful to us, but when we get to
93[`closures`][closures], we’ll talk about passing functions as arguments to
94other functions. For example, with [`iterators`][iterators], we can do this
95to convert a vector of `String`s into a vector of `Message::Write`s:
96
97```rust
98# enum Message {
99# Write(String),
100# }
101
102let v = vec!["Hello".to_string(), "World".to_string()];
103
104let v1: Vec<Message> = v.into_iter().map(Message::Write).collect();
105```
106
107[closures]: closures.html
108[iterators]: iterators.html