首页 > 解决方案 > 为什么我们使用 Option 枚举?

问题描述

我不明白Option枚举的用途。我读到 Rust 没有空值。Option枚举定义如下:

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

我阅读了它的实现,并遇到了这个例子:

fn main() {
    fn divide(numerator: f64, denominator: f64) -> Option<f64> {
        if denominator == 0.0 {
            None
        } else {
            Some(numerator / denominator)
        }
    }

    // The return value of the function is an option
    let result = divide(2.0, 3.0);

    // Pattern match to retrieve the value
    match result {
        // The division was valid
        Some(x) => println!("Result: {}", x),
        // The division was invalid
        None => println!("Cannot divide by 0"),
    }
}

当他们也可以这样做时:

fn main() {
    fn divide(numerator: f64, denominator: f64) -> String {
        if denominator == 0.0 {
            format!("Can't divide")
        } else {
            let x = numerator / denominator;
            format!("{}", x)
        }
    }

    let result = divide(2.0, 3.0);
    println!("{}", result);
}

两个程序输出:

0.6666666666666666

标签: enumsrust

解决方案


也许上面的例子不是一个很好的例子Option,但下面的例子Option最好地展示了:

fn main() {
    let name = String::from("naufil");
    println!(
        "Character at index 6: {}",
        match name.chars().nth(6) {
            Some(c) => c.to_string(),
            None => "No character at index 6!".to_string(),
        }
    )
}

当我们不确定第 6 个元素中是否有字符并且您不希望程序崩溃时,Option可以进行救援。这是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);

示例 6-5:使用match表达式的函数Option<i32>

让我们更详细地检查第一次执行plus_one。当我们调用 时,主体中plus_one(five)的变量将具有值。然后,我们将其与每个匹配臂进行比较。xplus_oneSome(5)

None => None,

Some(5)值与模式不匹配None,所以我们继续下一个手臂。

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

Some(5)匹配吗Some(i)?为什么是的!我们有相同的变体。i绑定到 中包含的值, Some因此i获取值5。然后执行匹配臂中的代码,因此我们将值加 1 并在里面i创建一个新Some6

现在让我们考虑plus_one示例 6-5 中的第二个调用,其中xis None。我们输入match并与第一臂进行比较。

None => None,

它匹配!没有要添加的值,所以程序停止并 None返回=>. 因为第一个手臂匹配,所以没有比较其他手臂。

组合match和枚举在许多情况下都很有用。你会在 Rust 代码中看到很多这种模式:match针对枚举,将变量绑定到里面的数据,然后基于它执行代码。一开始有点棘手,但一旦你习惯了它,你会希望你拥有所有语言的它。它一直是用户的最爱。


推荐阅读