简体   繁体   English

在 Rust 中使用 and_then 有条件地处理特定错误

[英]Conditionally Acting on Specific Error Using and_then in Rust

How do I know what error happened when piping Result s via and_then in Rust?我如何知道在 Rust 中通过and_then传递Result时发生了什么错误? For example using nested matches I could do this:例如使用嵌套匹配我可以这样做:

use std::num::ParseIntError;

fn get_num(n: u8) -> Result<u8, ParseIntError> {
   // Force a ParseIntError
   "foo ".parse()
}
fn add_one(n: u8) -> Result<u8, ParseIntError> {
    Ok(n + 1)
}
fn main() {
    match get_num(1) {
        Ok(n) => {
            match add_one(n) {
                Ok(n) => println!("adding one gives us: {}", n),
                Err(why) => println!("Error adding: {}", why)
            }
        },
        Err(why) => println!("Error getting number: {}", why),
    }
}

Or I can use and_then to pipe the result of the first function to the second and avoid a nested match:或者我可以使用and_then到 pipe 第一个 function 到第二个的结果并避免嵌套匹配:

match get_num(1).and_then(add_one) {
  Ok(n) => println!("Adding one gives us: {}", n),
  Err(why) => println!("Some error: {}.", why)
}

How do I conditionally and idiomatically determine the error in the second form, using and_then ?如何使用and_then有条件地和惯用地确定第二种形式的错误? Do I have to type check the error?我必须输入检查错误吗? Sure I can display the error like I did above, but let's say I want to preface it with something related to the kind of error it is?当然我可以像上面那样显示错误,但是假设我想在它前面加上与错误类型相关的内容?

The normal way would be to use map_err to convert the initial errors to something richer you control eg正常的方法是使用map_err将初始错误转换为您可以控制的更丰富的内容,例如

enum MyError {
    Parsing,
    Adding
}

get_num(1).map_err(|_| MyError::Parsing)
    .and_then(|v| add_one(v).map_err(|_| MyError::Adding)

sadly as you can see this requires using a lambda for the and_then callback: and_then must return the same error type as the input, so here it has to yield a Result<_, MyError> , wjhich is not the return type of add_one .遗憾的是,正如您所看到的,这需要使用 lambda 进行and_then回调: and_then必须返回与输入相同的错误类型,所以这里它必须产生Result<_, MyError> ,wjhich 不是add_one的返回类型。

And while in other situations we could recover somewhat with ?而在其他情况下,我们可以通过? , here the same original error type is split into two different values. ,这里相同的原始错误类型被分成两个不同的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM