我不明白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
也许上面的例子不是一个很好的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
会来救援。这是The 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)
,plus_one
体中的变量x
将具有 值Some(5)
.然后,我们将它与每个比赛臂进行比较。None => None,
Some(5)
值与模式None
不匹配,因此我们继续 下一只手臂。Some(i) => Some(i + 1),
Some(5)
匹配Some(i)
吗?为什么是这样!我们有相同的变体。这i
绑定到Some
中包含的值,所以i
取值5
。这 然后执行匹配臂中的代码,因此我们将 1 加到i
的值和 用我们的总6
创造新的Some
价值。现在让我们考虑示例 6-5 中
plus_one
的第二次调用,其中x
None
.我们进入match
并与第一臂进行比较。None => None,
它匹配!没有要添加到的值,因此程序停止并返回
None
=>
右侧的值。因为第一只手臂匹配,没有其他 武器进行比较。在许多情况下,组合
match
和枚举很有用。你会看到这个 在 Rust 代码中有很多模式:match
针对枚举,将变量绑定到 数据,然后基于它执行代码。一开始有点棘手,但是 一旦你习惯了它,你会希望你拥有所有语言。它 始终是用户的最爱。
使用Option enum
的原因与使用Result
枚举的原因相同。它允许程序员查看他们可能收到的返回值的广度,但不必挖掘代码,您不记得所有细节,或者从未见过。
Option
不是一个特殊的值,它只是一个枚举,就像Result
一样。您也可以使用类似以下内容:
enum Division_Result {
Successful(f64),
DividedByZero,
}
fn divide(numerator: f64, denominator: f64) -> Division_Result {
if denominator == 0.0 {
Division_Result::DividedByZero
} else {
Division_Result::Successful(numerator / denominator)
}
}
碰巧的是,可选值是您必须在程序中处理的一些最常见的值类型。它们将可选枚举烘焙到标准中,因为否则您将不得不处理每个人为可选值的简单概念提出自己的enum
。
返回enum
是对返回未包装的魔术值的改进,因为对程序员来说,返回值可能与他们想要的函数不同。