# 枚舉
> [enums.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/enums.md)
commit 31e39cd05c9b28c78b087aa9314f246b0b0b5cfa
Rust 中的一個`enum`是一個代表數個可能變量的數據的類型。每個變量都可選是否關聯數據:
~~~
enum Message {
Quit,
ChangeColor(i32, i32, i32),
Move { x: i32, y: i32 },
Write(String),
}
~~~
定義變量的語法與用來定義結構體的語法類似:你可以有不帶數據的變量(像類單元結構體),帶有命名數據的變量,和帶有未命名數據的變量(像元組結構體)。然而,不像單獨的結構體定義,一個`enum`是一個單獨的類型。一個枚舉的值可以匹配任何一個變量。因為這個原因,枚舉有時被叫做“集合類型”:枚舉可能值的集合是每一個變量可能值的集合的總和。
我們使用`::`語法來使用每個變量的名字:它們包含在`enum`名字自身中。這樣的話,以下的情況都是可行的:
~~~
# enum Message {
# Move { x: i32, y: i32 },
# }
let x: Message = Message::Move { x: 3, y: 4 };
enum BoardGameTurn {
Move { squares: i32 },
Pass,
}
let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };
~~~
這兩個變量都叫做`Move`,不過他們包含在枚舉名字中,他們可以無沖突的使用。
枚舉類型的一個值包含它是哪個變量的信息,以及任何與變量相關的數據。這有時被作為一個“標記的聯合”被提及。因為數據包括一個“標簽”表明它的類型是什么。編譯器使用這個信息來確保安全的訪問枚舉中的數據。例如,我們不能簡單的嘗試解構一個枚舉值,就像它是其中一個可能的變體那樣:
~~~
fn process_color_change(msg: Message) {
let Message::ChangeColor(r, g, b) = msg; // compile-time error
}
~~~
不支持這些操作(比較操作)可能看起來更像限制。不過這是一個我們可以克服的限制。有兩種方法:我們自己實現相等(比較),或通過[`match`](#)表達式模式匹配變量,你會在下一部分學到它。我們還不夠了解Rust如何實現相等,不過我們會在[特性](#)找到它們。
### 構造器作為函數(Constructors as functions)
一個枚舉的構造器總是可以像函數一樣使用。例如:
~~~
# enum Message {
# Write(String),
# }
let m = Message::Write("Hello, world".to_string());
~~~
與下面是一樣的:
~~~
# enum Message {
# Write(String),
# }
fn foo(x: String) -> Message {
Message::Write(x)
}
let x = foo("Hello, world".to_string());
~~~
這對我們沒有什么直接的幫助,直到我們要用到[閉包](#)時,這時我們要考慮將函數作為參數傳遞給其他函數。例如,使用[迭代器](#),我們可以這樣把一個`String`的vector轉換為一個`Message::Write`的vector:
~~~
# enum Message {
# Write(String),
# }
let v = vec!["Hello".to_string(), "World".to_string()];
let v1: Vec<Message> = v.into_iter().map(Message::Write).collect();
~~~
- 前言
- 貢獻者
- 1.介紹
- 2.準備
- 3.學習 Rust
- 3.1.猜猜看
- 3.2.哲學家就餐問題
- 3.3.其它語言中的 Rust
- 4.語法和語義
- 4.1.變量綁定
- 4.2.函數
- 4.3.原生類型
- 4.4.注釋
- 4.5.If語句
- 4.6.循環
- 4.7.所有權
- 4.8.引用和借用
- 4.9.生命周期
- 4.10.可變性
- 4.11.結構體
- 4.12.枚舉
- 4.13.匹配
- 4.14.模式
- 4.15.方法語法
- 4.16.Vectors
- 4.17.字符串
- 4.18.泛型
- 4.19.Traits
- 4.20.Drop
- 4.21.if let
- 4.22.trait 對象
- 4.23.閉包
- 4.24.通用函數調用語法
- 4.25.crate 和模塊
- 4.26.const和static
- 4.27.屬性
- 4.28.type別名
- 4.29.類型轉換
- 4.30.關聯類型
- 4.31.不定長類型
- 4.32.運算符和重載
- 4.33.Deref強制多態
- 4.34.宏
- 4.35.裸指針
- 4.36.不安全代碼
- 5.高效 Rust
- 5.1.棧和堆
- 5.2.測試
- 5.3.條件編譯
- 5.4.文檔
- 5.5.迭代器
- 5.6.并發
- 5.7.錯誤處理
- 5.8.選擇你的保證
- 5.9.外部函數接口
- 5.10.Borrow 和 AsRef
- 5.11.發布途徑
- 5.12.不使用標準庫
- 6.Rust 開發版
- 6.1.編譯器插件
- 6.2.內聯匯編
- 6.4.固有功能
- 6.5.語言項
- 6.6.鏈接進階
- 6.7.基準測試
- 6.8.裝箱語法和模式
- 6.9.切片模式
- 6.10.關聯常量
- 6.11.自定義內存分配器
- 7.詞匯表
- 8.語法索引
- 9.參考文獻
- 附錄:名詞中英文對照