我观察过几次这样的情况,我可能希望根据一堆操作的最终结果采取行动,我不关心哪个操作抛出了错误,只关心其中一个操作抛出了错误,或者它们都没有。我可以为此使用?
运算符,但它随后将错误传播给函数调用。我希望这样的东西能起作用:
fn do_something() {
let i = {
let w = function1()?;
let x = function2(z)?.function3()?;
x.y()?
};
if let Ok(item) = i {
// ..
} else {
// call to some other function or something..
}
// some more code here..
}
然而,这不起作用。是否有其他方法可以实现这种模式?我知道我可以将作用域包装在闭包中,但这感觉很难看,而且不惯用,特别是如果经常需要这样的行为。这可能表明我需要将函数分解为更小的函数,但是在
这样的情况下,这被证明是笨拙的。 let i = {
function1()?.function2()?.function3()
}
在中创建一个全新的函数是没有意义的。也许这并不是一种习惯的做事方式。如果是这样,我应该如何处理这个问题?您的示例实际上是不可复制的,因为它无法编译。所以我将给出一个我自己的例子。
你可以使用函数式的方法来组合你的方法调用。像这样:
fn main() {
let result = one()
.and_then(|_ok| two())// will be called if one() returned Ok, otherwise `result will contain the returned Err
.and_then(|_ok| three()); // will be called if two() returned Ok, otherwise `result will contain the returned Err
println!("Result: {:#?}", result);
}
fn one() -> Result<(), String> {
println!("one");
Ok(())
}
fn two() -> Result<(), String> {
println!("two");
Err("two".to_owned())
}
fn three() -> Result<(), String> {
println!("tree"); // won;t be called because `two()` returned an err
Ok(())
}
还有其他有用的组合子,如or_else()、map_or()、map_err()等。