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.

2.5 KiB

解构Option

在枚举那章,提到过Option枚举, 它用来解决Rust中变量是否有值的问题定义如下:

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

简单解释就是: 一个变量要么有值:Some(T), 要么为空: None.

那么现在的问题就是该如何去使用这个Option枚举类型,根据我们上一节的经验,可以通过match来实现。

因为Option,SomeNone都包含在prelude中,因此你可以直接通过名称来使用它们,而无需以Option::Some这种形式去使用,总之,千万不要因为形式变短了,而忘记SomeNone也是Option底下的枚举成员!

匹配 Option<T>

使用Option<T>,是为了从 Some 中取出其内部的 T 值以及处理没有值的情况,为了演示这一点,下面一起来编写一个函数,它获取一个 Option<i32>,如果其中含有一个值,将其加一;如果其中没有值,则函数返回 None 值:

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)

None => None,

首先是匹配None分支,因为值Some(5) 并不匹配模式 None,所以继续匹配下一个分支。

Some(i) => Some(i + 1),

Some(5)Some(i) 匹配吗?当然匹配!它们是相同的成员。i 绑定了 Some 中包含的值,因此 i 的值是 5。接着匹配分支的代码被执行,最后将 i 的值加一并返回一个含有值 6 的新 Some

传入参数None

接着考虑下plus_one 的第二个调用,这次传入的xNone 我们进入 match 并与第一个分支相比较。

None => None,

匹配上了!接着程序继续执行该分支后的代码:返回表达式None的值,也就是返回一个None,因为第一个分支就匹配到了,其他的分支将不再比较。