由于使用unwrap可能会出现问题,因为它在错误场景中崩溃,因此可能被认为是危险的使用。
如果我百分百确定它不会崩溃怎么办,就像在以下场景中一样:
if option.is_some() {
let value = option.unwrap();
}
Run Code Online (Sandbox Code Playgroud)
if option.is_some() {
let value = option.unwrap();
}
Run Code Online (Sandbox Code Playgroud)
由于我们已经检查过,Result因此Option使用时不会发生崩溃unwrap()。但是,我们可以使用matchor if let。在我看来,要么match要么if let用法更优雅。
让我们重点关注Result;我会回到Option最后。
的目的Result是发出信号,该结果可能成功,也可能因错误而失败。因此,它的任何使用都应该属于这一类。让我们忽略箱子Result因不可能失败的操作而返回的情况。
通过做你正在做的事情(检查if result.is_ok() 然后提取值),你实际上是在做同样的事情两次。第一次,您正在检查 的内容Result,第二次,您正在不安全地检查和提取。
match这确实可以用或 来完成map,并且两者都比 更惯用if。考虑一下这个例子:
您有一个实现以下特征的对象:
use std::io::{Error, ErrorKind};
trait Worker {
fn hours_left(&self) -> Result<u8, Error>;
fn allocate_hours(&mut self, hours: u8) -> Result<u8, Error>;
}
Run Code Online (Sandbox Code Playgroud)
我们假设hours_left()它的作用与罐头上的说明完全一致。我们还假设我们有一个可变的借用Worker。让我们实施一下allocate_hours()。
为此,我们显然需要检查我们的员工是否还有剩余时间可供分配。你可以像你的那样写:
fn allocate_hours(&mut self, hours: u8) {
let hours_left = self.hours_left();
if (hours_left.is_ok()) {
let remaining_hours = hours_left.unwrap();
if (remaining_hours < hours) {
return Err(Error::new(ErrorKind::NotFound, "Not enough hours left"));
}
// Do the actual operation and return
} else {
return hours_left;
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这种实现方式既笨重又低效。我们可以通过完全避免unwrapandif语句来简化这一点。
fn allocate_hours(&mut self, hours: u8) -> Result<u8, Error> {
self.hours_left()
.and_then(|hours_left| {
// We are certain that our worker is actually there to receive hours
// but we are not sure if he has enough hours. Check.
match hours_left {
x if x >= hours => Ok(x),
_ => Err(Error::new(ErrorKind::NotFound, "Not enough hours")),
}
})
.map(|hours_left| {
// At this point we are sure the worker has enough hours.
// Do the operations
})
}
Run Code Online (Sandbox Code Playgroud)
我们在这里用一石打死了多只鸟。我们使代码更具可读性、更易于遵循,并且删除了一大堆重复操作。这也开始看起来像 Rust,而不像 PHP ;-)
Option类似并且支持相同的操作。如果您想相应地处理OptionorResult和分支的内容,并且您正在使用unwrap,那么当您忘记打开某些东西时,您将不可避免地陷入许多陷阱。
在某些真实的情况下,你的程序应该会崩溃。对于那些,请考虑expect(&str)与unwrap()
| 归档时间: |
|
| 查看次数: |
978 次 |
| 最近记录: |