首页 > 解决方案 > 如何处理 unwrap_or_else 中的异常(Err)?

问题描述

struct OverflowError {}

fn test_unwrap() -> Result<String, OverflowError> {
    let a: Result<String, u8> = Err(100);

    let a: String = a.unwrap_or_else(|err| {
        if err < 100 {
            String::from("Ok")
        } else {
            // I want to return from the function (not just the closure)
            // This is compile error with error:
            // "the ? operator can only be used in a closure that returns Result or Option"
            Err(OverflowError {})?
        }
    });

    Ok(a)
}
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/lib.rs:13:13
   |
6  |       let a: String = a.unwrap_or_else(|err| {
   |  ______________________________________-
7  | |         if err < 100 {
8  | |             String::from("Ok")
9  | |         } else {
...  |
13 | |             Err(OverflowError {})?
   | |             ^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a closure that returns `std::string::String`
14 | |         }
15 | |     });
   | |_____- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `std::string::String`
   = note: required by `std::ops::Try::from_error`

这是我的代码的简化版本。基本上在unwrap_or_else闭包内部,可能存在条件错误(例如 IOError)。在这种情况下,我想提前终止函数(使用?)。但显然它不起作用,因为它当前处于闭包中,并且闭包不需要 Result 类型。

处理这个问题的最佳做法是什么?

标签: rust

解决方案


你想要的是or_else()

struct OverflowError {}

fn test_unwrap() -> Result<String, OverflowError> {
    let a: Result<String, u8> = Err(100);

    let a: String = a.or_else(|err| {
        if err < 100 {
            Ok(String::from("Ok"))
        } else {
            Err(OverflowError {})
        }
    })?;

    Ok(a)
}

简化:

struct OverflowError {}

fn test_unwrap() -> Result<String, OverflowError> {
    Err(100).or_else(|err| {
        if err < 100 {
            Ok(String::from("Ok"))
        } else {
            Err(OverflowError {})
        }
    })
}

推荐阅读