【问题标题】:Is it possible to use '?' operator in a scope? [duplicate]是否可以使用'?范围内的运算符? [复制]
【发布时间】:2021-07-24 11:10:47
【问题描述】:

我已经多次观察到这样一种情况,我可能想根据一堆操作的最终结果采取行动,我不在乎哪个操作引发了错误,只是其中一个发生了错误,或者没有一个他们做到了。 我可以为此使用? 运算符,但它会将错误传播到函数调用。我希望这样的事情会起作用:

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()
 }

创建一个全新的功能没有多大意义。 也许这甚至不是惯用的做事方式。如果是这样,我应该如何处理这个问题?

【问题讨论】:

  • 您正在寻找当前不稳定的try_blocks 功能。在此之前,您可以使用Result::and_then 链接多个结果,但您必须手动转换错误大小写。

标签: rust error-handling


【解决方案1】:

您的示例不是真正可重现的,因为它无法编译。所以我举一个我自己的例子。

您可以使用函数式方法来编写方法调用。像这样的:

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()等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2020-02-20
    相关资源
    最近更新 更多