math:強大的流程控制運算符
- 允許一個值與一系列模式進行比對,并執行比對模式對應的代碼
- 模式可以是字面值、變量名、通配符...
- 有點類似Java的switch case 味道
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
// 這裡 整個match 是一個表達式,結果會作為函數結果傳回
// coin 的值将與 會括号 => 左邊類容進行比對
// 比對上哪個,就執行 => 右邊的表達式,并傳回
match coin {
Coin::Penny => {
println!("Lucky penny!");
1
}
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
fn main() {}
綁定值得模式
- 比對的分支可以綁定到被比對對象的部分值(是以可以從enum變體中提取值)
// 友善輸出
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
// --snip--
}
// 添加變體
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
// 接收變體值
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
}
}
}
fn main() {
// 傳入變體值
value_in_cents(Coin::Quarter(UsState::Alaska));
}
比對Option<T>
上一章有提到 Option有兩個枚舉值
- None 代表沒有
- Some 代表有,傳回的就是T
fn main() {
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
}
match 比對必須窮舉所有的可能
- 必須窮舉所有可能
- 實在太多,可以使用 通配符 other 或 _ 占位符 來代替不想窮舉的值
正如上面示例Option窮舉了它的兩個枚舉值,那如果不窮舉編譯會失敗:
fn main() {
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
Some(i) => Some(i + 1),
}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
}
error[E0004]: non-exhaustive patterns: `None` not covered
--> src\main.rs:3:15
|
3 | match x {
| ^ pattern `None` not covered
|
note: `Option<i32>` defined here
--> D:\tools\rust\rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\option.rs:522:5
|
518 | pub enum Option<T> {
| ------------------
...
522 | None,
| ^^^^ not covered
= note: the matched value is of type `Option<i32>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
4 ~ Some(i) => Some(i + 1),
5 ~ None => todo!(),
|
通配符或_占位符
fn main() {
let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
other => move_player(other),
// 或者
// _ => move_player(other),
// 空處理
// _ => (),
}
fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}
}