# 匹配
> [match.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/match.md)
commit fc4bb5f77060b5822f25edbabbdf7a1d48a7f8fe
一個簡單的[`if`](#)/`else`往往是不夠的,因為你可能有兩個或更多個選項。這樣`else`也會變得異常復雜。Rust 有一個`match`關鍵字,它可以讓你有效的取代復雜的`if`/`else`組。看看下面的代碼:
~~~
let x = 5;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
4 => println!("four"),
5 => println!("five"),
_ => println!("something else"),
}
~~~
`match`使用一個表達式然后基于它的值分支。每個分支都是`val => expression`這種形式。當匹配到一個分支,它的表達式將被執行。`match`屬于“模式匹配”的范疇,`match`是它的一個實現。有[一個整個關于模式的部分](#)講到了所有可能的模式。
那么這有什么巨大的優勢呢?這確實有優勢。第一,`match`強制*窮盡性檢查*(*exhaustiveness checking*)。你看到了最后那個下劃線開頭的分支了嗎?如果去掉它,Rust 將會給我們一個錯誤:
~~~
error: non-exhaustive patterns: `_` not covered
~~~
Rust 試圖告訴我們忘記了一個值。編譯器從`x`推斷它可以是任何正的 32 位整型值;例如從 1 到 2,147,483,647。`_`就像一個*匹配所有*的分支,它會捕獲所有沒有被`match`分支捕獲的所有可能值。如你所見,在上個例子中,我們提供了 1 到 5 的`mtach`分支,如果`x`是 6 或者其他值,那么它會被`_`捕獲。
`match`也是一個表達式,也就是說它可以用在`let`綁定的右側或者其它直接用到表達式的地方:
~~~
let x = 5;
let number = match x {
1 => "one",
2 => "two",
3 => "three",
4 => "four",
5 => "five",
_ => "something else",
};
~~~
有時,這是一個把一種類型的數據轉換為另一個類型的好方法。
### 匹配枚舉(Matching on enums)
`match`的另一個重要的作用是處理枚舉的可能變量:
~~~
enum Message {
Quit,
ChangeColor(i32, i32, i32),
Move { x: i32, y: i32 },
Write(String),
}
fn quit() { /* ... */ }
fn change_color(r: i32, g: i32, b: i32) { /* ... */ }
fn move_cursor(x: i32, y: i32) { /* ... */ }
fn process_message(msg: Message) {
match msg {
Message::Quit => quit(),
Message::ChangeColor(r, g, b) => change_color(r, g, b),
Message::Move { x: x, y: y } => move_cursor(x, y),
Message::Write(s) => println!("{}", s),
};
}
~~~
再一次,Rust編譯器檢查窮盡性,所以它要求對每一個枚舉的變量都有一個匹配分支。如果你忽略了一個,除非你用`_`否則它會給你一個編譯時錯誤。
與之前的`match`的作用不同,你不能用常規的`if`語句來做這些。你可以使用[if let](#)語句,它可以被看作是一個`match`的簡略形式。
- 前言
- 貢獻者
- 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.參考文獻
- 附錄:名詞中英文對照