enums - 为什么我们使用 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
解决方案
也许上面的例子不是一个很好的例子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)
的变量将具有值。然后,我们将其与每个匹配臂进行比较。x
plus_one
Some(5)
None => None,
该
Some(5)
值与模式不匹配None
,所以我们继续下一个手臂。Some(i) => Some(i + 1),
Some(5)
匹配吗Some(i)
?为什么是的!我们有相同的变体。i
绑定到 中包含的值,Some
因此i
获取值5
。然后执行匹配臂中的代码,因此我们将值加 1 并在里面i
创建一个新Some
值6
。现在让我们考虑
plus_one
示例 6-5 中的第二个调用,其中x
isNone
。我们输入match
并与第一臂进行比较。None => None,
它匹配!没有要添加的值,所以程序停止并
None
返回=>
. 因为第一个手臂匹配,所以没有比较其他手臂。组合
match
和枚举在许多情况下都很有用。你会在 Rust 代码中看到很多这种模式:match
针对枚举,将变量绑定到里面的数据,然后基于它执行代码。一开始有点棘手,但一旦你习惯了它,你会希望你拥有所有语言的它。它一直是用户的最爱。
推荐阅读
- python - Qt Creator 缺少一些模块
- javascript - Discord bot 无法从计算机读取文件,即使它存在
- vba - VBA-过滤不必要的文件夹
- sql-server - 为什么函数 CONVERT 对结果进行四舍五入?
- python - nltk 的 wordnet 中的 valueError
- c# - What is the proper way of getting the HTTP request method in an AuthorizationHandler
? - java - Spring KafkaTemplate 在 OpenShift 上找不到引导服务器
- oracle - 错误地与组相关的数据仓库错误
- c# - AspectFill 不适用于 xamarin 中 SkiaSharp 中调整大小的图像,我该怎么办?
- google-apps-script - 如何解决 getrange 错误“范围内的行数必须至少为 1”?