枚举

Option

Option<T> 是一个标准库的一部分。定义如下:

enum Option<T> {
   Some(T),
   None,
}

Option (包括 Some 和 None)是开箱即用的,无需导入任何模块。使用 Some 时 Rust 可以自动推导出参数类型,但是使用 None 时必须手动指定 T 的类型:

let some_number = Some(5);

let absent_number: Option<i32> = None;

由于 Option 不能和 T 直接进行运算,因此运算之前必须先拿到枚举中的值,这一过程保证了 None 一定被处理了:

fn main() {
   let mut x = Some(4);
   match x.as_mut() {
      Some(v) => {
            *v *= 2;
            println!("{}", v)
      }
      None => println!("None"),
   }
}

match

match 实际上是一个类似 C++ 中 switch 的语法,但是要更加强大:

enum Coin {
   Penny,
   Nickel,
   Dime,
   Quarter,
}

fn value_in_cents(coin: Coin) -> u8 {
   match coin {
      Coin::Penny => 1,
      Coin::Nickel => 5,
      Coin::Dime => 10,
      Coin::Quarter => 25,
   }
}

由于枚举中可以添加值,因此匹配过程中可以使用参数接受值,这也是唯一可以访问到枚举值的方式:

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
      },
   }
}

但是,match 必须要覆盖所有可能的情况,否则无法通过编译,因此产生了一个类似于 switch 中 default 的语法:

match some_u8_value {
   3 => println!("three"),
   _ => (),
}

其中小括号就是 unit 值,因此 _ 什么也不会发生

if let

if let 用于匹配单一情况:

let x = 4;
if let 4 = x {
   println!("four");
}

唯一需要注意的是变量放到后面,值放到前面

同样也能用来接受值:

let mut count = 0;
if let Coin::Quarter(state) = coin {
   println!("State quarter from {:?}!", state);
}