通过对《Rust 程序设计语言》,《通过例子学 Rust 中文版》以及令狐一冲老师对相关知识点的学习总结而成。
rust -枚举和模式匹配学习(二)
1 Option定义形式
空值尝试表达的概念仍然是有意义的:空值是一个因为某种原因目前无效或缺失的值。
问题不在于概念而在于具体的实现。为此,Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是 Option,而且它定义于标准库中,其形式为:
enum Option<T> {
Some(T),
None,
}
Option 枚举是如此有用以至于它甚至被包含在了 prelude 之中,你不需要将其显式引入作用域。另外,它的成员也是如此,可以不需要 Option:: 前缀来直接使用 Some 和 None。即便如此 Option 也仍是常规的枚举,Some(T) 和 None 仍是 Option 的成员。
注: 语法是一个泛型类型参数。
2 Option的使用方式
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;
Option 和 T(这里 T 可以是任何类型)是不同的类型,编译器不允许像一个肯定有效的值那样使用 Option。
3 匹配 Option
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
fn main() {
let five = Some(5);
let none = plus_one(None);
}
4 匹配 Some(T)
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
fn main() {
let five = Some(5);
let none = plus_one(None);
}
让我们更仔细地检查 plus_one 的第一行操作。当调用 plus_one(five) 时,plus_one 函数体中的 x 将会是值 Some(5)。接着将其与每个分支比较。
None => None,
值 Some(5) 并不匹配模式 None,所以继续进行下一个分支。
Some(i) => Some(i + 1),
Some(5) 与 Some(i) 匹配吗?当然匹配!它们是相同的成员。i 绑定了 Some 中包含的值,所以 i 的值是 5。接着匹配分支的代码被执行,所以我们将 i 的值加一并返回一个含有值 6 的新 Some。
接着考虑下示例中 plus_one 的第二个调用,这里 x 是 None。我们进入 match 并与第一个分支相比较。
None => None,
匹配上了!这里没有值来加一,所以程序结束并返回 => 右侧的值 None,因为第一个分支就匹配到了,其他的分支将不再比较。
下面是一个对Some(T)匹配做进一步处理的例子。
fn plus_one(x: Option<i32>) -> Option<i32> {
match x {
None => None,
Some(i) => Some(i + 1),
}
}
fn main() {
let five = Some(5);
let res = plus_one(five);
match res { //此处的match要把所有的情况都处理完
Some(i) => println!("res = {}", i),
None => println!("None"),
};
}
5 if let 简单控制流
match的时候要把它所有的情况都做出处理,但是存在我们只需要处理其中仅关心的一两种模式的情形。
if let 语法让我们以一种不那么冗长的方式结合 if 和 let,来处理只匹配一个模式的值而忽略其他模式的情况。
如下所举的示例:虽然我们只关注了Some(T)的match分支,但是其他不关心的分支还是需要通过_
通配符去做对应的处理。
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
下面我们来看if let的使用方式:
let some_u8_value = Some(0u8);
if let Some(3) = some_u8_value {
println!("three");
}
if let Some(value) = plus_one(five) {
println!("value is {}", value);
}