枚举

enum 关键字可以创建枚举类型(enumeration),该类型的实例只能在数个可能的取值中 取一种。任何一个合法的 struct 同时也是合法的 enum 取值。

1. // 该属性用于隐藏对未使用代码的警告。
2. #![allow(dead_code)]

4. // 创建一个 `enum`(枚举)来对 web 事件分类。注意变量名和类型共同指定了 `enum`
5. // 取值的种类:`PageLoad` 不等于 `PageUnload`,`KeyPress(char)` 不等于
6. // `Paste(String)`。各个取值不同,互相独立。
7. enum WebEvent {
8. // 一个 `enum` 可以是单元结构体(称为 `unit-like` 或 `unit`),
9. PageLoad,
10. PageUnload,
11. // 或者一个元组结构体,
12. KeyPress(char),
13. Paste(String),
14. // 或者一个普通的结构体。
15. Click { x: i64, y: i64 }
16. }

18. // 此函数将一个 `WebEvent` enum 作为参数,无返回值。
19. fn inspect(event: WebEvent) {
20. match event {
21. WebEvent::PageLoad => println!("page loaded"),
22. WebEvent::PageUnload => println!("page unloaded"),
23. // 从 `enum` 里解构出 `c`。
24. WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
25. WebEvent::Paste(s) => println!("pasted \"{}\".", s),
26. // 把 `Click` 解构给 `x` and `y`。
27. WebEvent::Click { x, y } => {
28. println!("clicked at x={}, y={}.", x, y);
29. },
30. }
31. }

33. fn main() {
34. let pressed = WebEvent::KeyPress('x');
35. // `to_owned()` 从一个字符串切片中创建一个具有所有权的 `String`。
36. let pasted  = WebEvent::Paste("my text".to_owned());
37. let click   = WebEvent::Click { x: 20, y: 80 };
38. let load    = WebEvent::PageLoad;
39. let unload  = WebEvent::PageUnload;

41. inspect(pressed);
42. inspect(pasted);
43. inspect(click);
44. inspect(load);
45. inspect(unload);
46. }

类型别名

若使用类型别名,则可以通过其别名引用每个枚举变量。当枚举的名称太长或者太一般化,且你想要对其重命名,那么这对你会有所帮助。

1. enum VeryVerboseEnumOfThingsToDoWithNumbers {
2. Add,
3. Subtract,
4. }

6. // Creates a type alias
7. type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;

9. fn main() {
10. // We can refer to each variant via its alias, not its long and inconvenient
11. // name.
12. let x = Operations::Add;
13. }

最常见的情况就是在 impl 块中使用 Self 别名。

1. enum VeryVerboseEnumOfThingsToDoWithNumbers {
2. Add,
3. Subtract,
4. }

6. impl VeryVerboseEnumOfThingsToDoWithNumbers {
7. fn run(&self, x: i32, y: i32) -> i32 {
8. match self {
9. Self::Add => x + y,
10. Self::Subtract => x - y,
11. }
12. }
13. }

该功能已在 Rust 中稳定化, 可以阅读 [stabilization report][aliasreport] 来了解更多有关枚举和类型别名的知识。

参见:

match, fn, 和 String, [“Type alias enum variants” RFC][type_alias_rfc]