枚举与模式匹配

1 枚举

使用enum定义一个枚举类型,使用逗号分割开枚举的成员:

例1.1:

enum IpAddrKind {
V4,
V6,
}

使用如下方法创建枚举类型的不同成员的实例:

例1.2:

fn main(){
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
}

在结构体中,可以使用枚举类型作为其字段类型:

例1.3:

enum IpAddrKind {
V4,
V6,
}
struct IpAddr {
kind: IpAddrKind,
address: String,
}
fn main(){
let home = IpAddr {
kind: IpAddrKind::V4,
address: String::from("127.0.0.1"),
};
let loopback = IpAddr {
kind: IpAddrKind::V6,
address: String::from("::1"),
};
}

可以为每个成员附上不同的数据类型,当然也可以是结构体等类型:

例1.4:

enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
fn main(){
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
}

match 控制流结构:

例1.5:

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

option 枚举

option定义于标准库下,可以不需要Option::前缀来直接使用SomeNone

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

<T>意味着Option枚举的Some成员可以包含任意类型的数据,同时每一个用于 T 位置的具体类型使得Option<T>整体作为不同的类型。

例1.6:

let some_number = Some(5);
let some_char = Some('e');
let absent_number: Option<i32> = None;

在对Option<T>进行运算之前必须将其转换为T

例1.7:

fn main() {
let x: i8 = 5;
let y: Option<i8> = Some(5);

let sum = match y {
Some(value) => x + value, // 如果 y 有值,执行加法
None => x, // 如果 y 是 None,直接返回 x
};

println!("Sum: {}", sum);
}
// 使用 if let 简化
fn main() {
let x: i8 = 5;
let y: Option<i8> = Some(5);

let mut sum = x;
if let Some(value) = y {
sum += value; // 如果 y 是 Some,则加上值
}

println!("Sum: {}", sum);
}

2 通配模式与 _ 占位符

match匹配的最后一个分支使用other符号表达未被特殊列出的值。

例2.1:

let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
other => move_player(other),
}

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}

当不想使用通配模式获取的值时,使用 _ ,这是一个特殊的模式,可以匹配任意值而不绑定到该值。

例2.2:

let dice_roll = 9;
match dice_roll {
3 => add_fancy_hat(),
7 => remove_fancy_hat(),
_ => reroll(),
}

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn reroll() {}