使用match(如bar
)似乎是一种常见的方法。
#[derive(Debug)]
pub enum MyErrors {
SomeError,
}
fn foo(x: Option<u64>) -> Result<u64, MyErrors> {
if x.is_none() {
return Err(MyErrors::SomeError);
}
// .. some long code where more options
// are checked and matched
// The ok here is just so the code is simple and compiles
Ok(x.unwrap() * 2)
}
fn bar(x: Option<u64>) -> Result<u64, MyErrors> {
match x {
None => {
return Err(MyErrors::SomeError)?;
}
Some(v) => {
// .. some long code where more options
// are checked and matched
// The ok here is just so the code is simple and compiles
Ok(x.unwrap() * 2)
}
}
}
fn main() {
foo(Some(1));
bar(Some(2));
}
字符串
然而,提前返回(比如在foo
中)会大大减少代码的嵌套程度。如果多次需要打开选项或返回错误,那么bar这样的代码就会嵌套得很深。
在空选项的情况下,提前返回错误的推荐做法是什么?
2条答案
按热度按时间iaqfqrcu1#
如果由于内部逻辑复杂而不希望使用更长的方法链,那么仍然有一些可读的低成本选项。
ok_or
和?
我们可以将一个
Option
转换为一个Result
,并带有所需的错误,然后立即使用?
操作符对其进行解包。这种解决方案可能提供了最少的错误,并且可以很容易地用于“解包”多个Option
。字符串
这将评估
ok_or
内部的错误,而不管它是否会被实际使用。如果这个计算是昂贵的,那么ok_or_else
,它会产生延迟的错误,将更有效(related question)。if let
如果嵌套,此解决方案仍然会导致代码阶梯,但如果
else
分支逻辑涉及更多,则可能更合适。型
dtcbnfnu2#
从Rust 1.65开始,你可以使用let-else语句:
字符串