You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
2.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 解构Option
在枚举那章,提到过 `Option` 枚举,它用来解决 Rust 中变量是否有值的问题,定义如下:
```rust
enum Option<T> {
Some(T),
None,
}
```
简单解释就是: **一个变量要么有值:`Some(T)`, 要么为空:`None`**。
那么现在的问题就是该如何去使用这个 `Option` 枚举类型,根据我们上一节的经验,可以通过 `match` 来实现。
> 因为 `Option``Some``None` 都包含在 `prelude` 中,因此你可以直接通过名称来使用它们,而无需以 `Option::Some` 这种形式去使用,总之,千万不要因为调用路径变短了,就忘记 `Some` 和 `None` 也是 `Option` 底下的枚举成员!
## 匹配 `Option<T>`
使用 `Option<T>`,是为了从 `Some` 中取出其内部的 `T` 值以及处理没有值的情况,为了演示这一点,下面一起来编写一个函数,它获取一个 `Option<i32>`,如果其中含有一个值,将其加一;如果其中没有值,则函数返回 `None` 值:
```rust
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);
```
`plus_one` 接受一个 `Option<i32>` 类型的参数,同时返回一个 `Option<i32>` 类型的值(这种形式的函数在标准库内随处所见),在该函数的内部处理中,如果传入的是一个 `None` ,则返回一个 `None` 且不做任何处理;如果传入的是一个 `Some(i32)`,则通过模式绑定,把其中的值绑定到变量 `i` 上,然后返回 `i+1` 的值,同时用 `Some` 进行包裹。
为了进一步说明,假设 `plus_one` 函数接受的参数值x是 `Some(5)`,来看看具体的分支匹配情况:
#### 传入参数 `Some(5)`
```rust,ignore
None => None,
```
首先是匹配 `None` 分支,因为值 `Some(5)` 并不匹配模式 `None`,所以继续匹配下一个分支。
```rust,ignore
Some(i) => Some(i + 1),
```
`Some(5)``Some(i)` 匹配吗?当然匹配!它们是相同的成员。`i` 绑定了 `Some` 中包含的值,因此 `i` 的值是 `5`。接着匹配分支的代码被执行,最后将 `i` 的值加一并返回一个含有值 `6` 的新 `Some`
#### 传入参数None
接着考虑下 `plus_one` 的第二个调用,这次传入的 `x``None` 我们进入 `match` 并与第一个分支相比较。
```rust,ignore
None => None,
```
匹配上了!接着程序继续执行该分支后的代码:返回表达式 `None` 的值,也就是返回一个 `None`,因为第一个分支就匹配到了,其他的分支将不再比较。