Appearance
枚举和匹配
Enum
rust
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
可以这么理解,IpAddr::V4() 是一个函数调用,以 String 为参数返回 IpAddr 类型。
rust
impl Message {
fn call(&self) {
// method body would be defined here
}
}
let m = Message::Write(String::from("hello"));
m.call();
Option
标准库自带一个叫 Option<T> 的 Enum,用于处理数据可能为空的情况。
rust
enum Option<T> {
None,
Some(T),
}
Option、Some、None 都通过 prelude 自动带入作用域,不需要手动引入。
注意 5 和 Some(5) 并不是一个东西,不能直接相加,需要后续处理才能使用,这也强迫你尽量处理 None 的情况,当然你还是可以逃课的,但前提是你必须知道你在做什么。
match
rust
#[derive(Debug)] // so we can inspect the state in a minute
enum UsState {
Alabama,
Alaska,
// --snip--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => {
println!("Lucky penny!");
1
}
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
}
}
}
上例就是对 coin 的值进行匹配,并运行函数。对于传入了值的 Quarter,运行函数时就直接把值当成参数传进去了(其实,也挺符合直觉的)。
Option 的 match
rust
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 时,你必须处理可能匹配到的所有情况,否则编译报错。
rust
fn main() {
let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
other => move_player(other),
// _ => reroll(),
}
fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}
}
匹配所有情况不代表要把所有选项都写一遍,使用 other 或 _ 可以简单处理剩余所有情况。
if let
与 match 处理所有情况相反,if let 用于更方便地处理某一特定情况,其他情况全部 else。
rust
fn main() {
let coin = Coin::Penny;
let mut count = 0;
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
}