天天看點

Rust程式設計語言-match控制流結構

作者:程式員小豬

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) {}
}
           

繼續閱讀