Rust 笔记 - 枚举与模式匹配

《Rust编程语言》笔记之二

枚举

创建枚举的两种方式

1
2
3
4
5
6
7
8
9
enum IpAddrKind {
V4,
V6,
}

enum IpAddrKind {
V4(String),
V6(String),
}

使用第二种人方式可以直接给枚举赋值,而且枚举的数据类型可以不相同:

1
2
3
4
enum IpAddrKind2 {
V4(u8, u8, u8, u8),
V6(String),
}

枚举中可以是任意的数据类型:struct, enum 等等。

定义方法

使用impl关键字可以给枚举定义方法:

1
2
3
4
5
6
7
8
9
10
enum IpAddrKind {
V4(u8, u8, u8, u8),
V6(String),
}

impl IpAddrKind {
fn call(&self) {
println!("this is the method of a enum");
}
}

Option枚举

rust中没有空值,但是存在一个表达空值的枚举, Option:

1
2
3
4
enum Option<T> {
Some<T>,
None,
}

可以只用Option定义一个可能为空的值:

1
2
let age = Some(8);
println!("{:?}", age); // Some(8)

Option的存在保证了非Option为空值,少去很多预防性的代码,同时也减少了许多因为忘了预防性代码而导致的bug

match控制流运算符

match允许我们将一个值与一系列的模式相比较并根据相匹配的模式执行相应代码。
模式可以由字面值、变量、通配符和许多其他内容构成。

1
2
3
4
5
6
7
8
9
10
11
12
match coin {
Coin::Penny => {
println!("Luck penny");
1
}
Coin::Nickel => 5,
Coin::Dim => 10,
Coin::Quarter(state) => { // 绑定值的模式匹配
println!("State quarter from {:?}!", state);
25
}
}

每个分支关联的代码是一个表达式,表达式的返回值是整个match表达式的值。

配置Option

1
2
3
4
match x {
Some(i) => Some(i + 1),
None => None,
}

可以使用_通配符来匹配其余的情况。

1
2
3
4
5
6
7
let value = 10;
match value {
1 => println!("1"),
2 => println!("2"),
3 => println!("3"),
_ => (),
};

偶然发现match中的各个分支不能返回不同的数据类型

if let控制流

如果只需要匹配一个模式的话,match显得有些冗余, rust提供了if let表达式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
}

enum Coin {
Penny,
Nickel,
Dim,
Quarter(UsState),
}

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

如上图, if let表达式后可以有else语句。

总结

没有空值的概念还是挺新奇的,只是没有实战经验还不太确定这样的特性是不是真的对编写安全的代码有帮助。
match语句和其它语言的switch语句比较像。