match.md
commit fc4bb5f77060b5822f25edbabbdf7a1d48a7f8fe
一個簡單的[if
](If If語句.md)/else
往往是不夠的,因為你可能有兩個或更多個選項。這樣else
也會變得異常復(fù)雜。Rust 有一個match
關(guān)鍵字,它可以讓你有效的取代復(fù)雜的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
這種形式。當匹配到一個分支,它的表達式將被執(zhí)行。match
屬于“模式匹配”的范疇,match
是它的一個實現(xiàn)。有[一個整個關(guān)于模式的部分](Patterns 模式.md)講到了所有可能的模式。
那么這有什么巨大的優(yōu)勢呢?這確實有優(yōu)勢。第一,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
綁定的右側(cè)或者其它直接用到表達式的地方:
let x = 5;
let number = match x {
1 => "one",
2 => "two",
3 => "three",
4 => "four",
5 => "five",
_ => "something else",
};
有時,這是一個把一種類型的數(shù)據(jù)轉(zhuǎn)換為另一個類型的好方法。
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
的作用不同,你不能用常規(guī)的if
語句來做這些。你可以使用[if let](if let.md)語句,它可以被看作是一個match
的簡略形式。