Enum 和模式匹配
enum 的简单用法是:
enum IpAddrKind {
V4,
V6,
}
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
Enum 也可以有关联值:
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);;
let loopback = IpAddr::V6(String::from("::1"));
当 enum 的关联值是 Copy
类型时, 对应的 enum 对象是在栈上分配的, 否则是在堆上.
再看一个复杂的例子, 这个例子中 enum 的关联值有匿名 struct:
struct SomeType;
enum Message {
Quit,
Move { x: i32, y: i32 }, // 匿名结构体
Write(String), // 普通 struct
Read(SomeType), // Unit like struct
ChangeColor(i32, i32, i32),
}
和 struct 类似, enum 也可以定义 方法:
impl Message {
fn call(&self) {
// method body would be defined here
}
}
Rust 中的 Option
enum
Rust 中没有空指针的概念, 而是通过 Option
中的 None
值表示空:
enum Option<T> {
None,
Some(T),
}
let some_number = Some(5);
let some_char = Some('e');
let absent_number: Option<i32> = None;
这样可以完全避免出现空指针误用的情况.
使用 match
进行模式匹配
语法上比较简单:
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,
}
}
如果要在匹配过程中抽取关联值, 则可以:
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
}
}
}
// 对 Option 的匹配:
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
还可以通过 _
忽略其它的分支(arm):
let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
// 其它情况的处理, 类似 switch 的 default 块
_ => reroll(),
}
使用 if let
进行精确匹配
语法和 swift 的类似, 只是需要将 enum 值放前面:
let config_max = Some(3u8);
if let Some(max) = config_max {
println!("The maximum is configured to be {}", max);
} else {
println!("no value here");
}