鍍金池/ 教程/ Java/ 枚舉
哲學(xué)家就餐問題
鏈接進(jìn)階
名詞中英文對照
測試
引用和借用
泛型
方法語法
函數(shù)
不安全代碼
并發(fā)
裝箱語法和模式
注釋
棧和堆
運(yùn)算符與重載
語法索引
文檔
固有功能
所有權(quán)
循環(huán)
通用函數(shù)調(diào)用語法
不定長類型
<code>const</code> 和 <code>static</code>
迭代器
其他語言中的 Rust
枚舉
詞匯表
If語句
猜猜看
錯誤處理
生命周期
編譯器插件
發(fā)布途徑
閉包
trait 對象
不使用標(biāo)準(zhǔn)庫
關(guān)聯(lián)常量
外部函數(shù)接口(FFI)
類型轉(zhuǎn)換
原生類型
匹配
參考文獻(xiàn)
Rust 編程語言
內(nèi)聯(lián)匯編
條件編譯
選擇你的保證
學(xué)習(xí) Rust
`type`別名
自定義內(nèi)存分配器
屬性
if let
高效 Rust
可變性
語法和語義
模式
基準(zhǔn)測試
結(jié)構(gòu)體
變量綁定
語言項
切片模式
<code>Deref</code> 強(qiáng)制多態(tài)
關(guān)聯(lián)類型
裸指針
<code>Borrow</code> 和 <code>AsRef</code>
準(zhǔn)備
Rust 開發(fā)版
字符串

枚舉

enums.md
commit 31e39cd05c9b28c78b087aa9314f246b0b0b5cfa

Rust 中的一個enum是一個代表數(shù)個可能變量的數(shù)據(jù)的類型。每個變量都可選是否關(guān)聯(lián)數(shù)據(jù):

enum Message {
    Quit,
    ChangeColor(i32, i32, i32),
    Move { x: i32, y: i32 },
    Write(String),
}

定義變量的語法與用來定義結(jié)構(gòu)體的語法類似:你可以有不帶數(shù)據(jù)的變量(像類單元結(jié)構(gòu)體),帶有命名數(shù)據(jù)的變量,和帶有未命名數(shù)據(jù)的變量(像元組結(jié)構(gòu)體)。然而,不像單獨(dú)的結(jié)構(gòu)體定義,一個enum是一個單獨(dú)的類型。一個枚舉的值可以匹配任何一個變量。因為這個原因,枚舉有時被叫做“集合類型”:枚舉可能值的集合是每一個變量可能值的集合的總和。

我們使用::語法來使用每個變量的名字:它們包含在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,不過他們包含在枚舉名字中,他們可以無沖突的使用。

枚舉類型的一個值包含它是哪個變量的信息,以及任何與變量相關(guān)的數(shù)據(jù)。這有時被作為一個“標(biāo)記的聯(lián)合”被提及。因為數(shù)據(jù)包括一個“標(biāo)簽”表明它的類型是什么。編譯器使用這個信息來確保安全的訪問枚舉中的數(shù)據(jù)。例如,我們不能簡單的嘗試解構(gòu)一個枚舉值,就像它是其中一個可能的變體那樣:

fn process_color_change(msg: Message) {
    let Message::ChangeColor(r, g, b) = msg; // compile-time error
}

不支持這些操作(比較操作)可能看起來更像限制。不過這是一個我們可以克服的限制。有兩種方法:我們自己實現(xiàn)相等(比較),或通過[match ](Match 匹配.md)表達(dá)式模式匹配變量,你會在下一部分學(xué)到它。我們還不夠了解Rust如何實現(xiàn)相等,不過我們會在特性找到它們。

構(gòu)造器作為函數(shù)(Constructors as functions)

一個枚舉的構(gòu)造器總是可以像函數(shù)一樣使用。例如:

# 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());

這對我們沒有什么直接的幫助,直到我們要用到[閉包](Closures 閉包.md)時,這時我們要考慮將函數(shù)作為參數(shù)傳遞給其他函數(shù)。例如,使用[迭代器](Iterators 迭代器.md),我們可以這樣把一個String的vector轉(zhuǎn)換為一個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();
上一篇:裝箱語法和模式下一篇:猜猜看