枚举

enum 关键字允许创建一个从数个不同取值中选其一的枚举类型(enumeration)。任何一个在 struct 中合法的取值在 enum 中也合法。

  1. // 该属性用于隐藏对未使用代码的警告。
  2. #![allow(dead_code)]
  3. // 创建一个 `enum`(枚举)来对 web 事件分类。注意变量名和类型共同指定了 `enum`
  4. // 取值的种类:`PageLoad` 不等于 `PageUnload`,`KeyPress(char)` 不等于
  5. // `Paste(String)`。各个取值不同,互相独立。
  6. enum WebEvent {
  7. // 一个 `enum` 可以是单元结构体(称为 `unit-like` 或 `unit`),
  8. PageLoad,
  9. PageUnload,
  10. // 或者一个元组结构体,
  11. KeyPress(char),
  12. Paste(String),
  13. // 或者一个普通的结构体。
  14. Click { x: i64, y: i64 }
  15. }
  16. // 此函数将一个 `WebEvent` enum 作为参数,无返回值。
  17. fn inspect(event: WebEvent) {
  18. match event {
  19. WebEvent::PageLoad => println!("page loaded"),
  20. WebEvent::PageUnload => println!("page unloaded"),
  21. // 从 `enum` 里解构出 `c`。
  22. WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
  23. WebEvent::Paste(s) => println!("pasted \"{}\".", s),
  24. // 把 `Click` 解构给 `x` and `y`。
  25. WebEvent::Click { x, y } => {
  26. println!("clicked at x={}, y={}.", x, y);
  27. },
  28. }
  29. }
  30. fn main() {
  31. let pressed = WebEvent::KeyPress('x');
  32. // `to_owned()` 从一个字符串切片中创建一个具有所有权的 `String`。
  33. let pasted = WebEvent::Paste("my text".to_owned());
  34. let click = WebEvent::Click { x: 20, y: 80 };
  35. let load = WebEvent::PageLoad;
  36. let unload = WebEvent::PageUnload;
  37. inspect(pressed);
  38. inspect(pasted);
  39. inspect(click);
  40. inspect(load);
  41. inspect(unload);
  42. }

类型别名

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

  1. enum VeryVerboseEnumOfThingsToDoWithNumbers {
  2. Add,
  3. Subtract,
  4. }
  5. // 创建一个类型别名
  6. type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;
  7. fn main() {
  8. // 我们可以通过别名引用每个枚举变量,避免使用又长又不方便的枚举名字
  9. let x = Operations::Add;
  10. }

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

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

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

参见:

match, fn, 和 String, “类型别名枚举变量” 的 RFC