如何在Rust中传播错误?

时间:2019-01-24 09:12:38

标签: if-statement rust

有没有一种很好的方法可以在Rust中传播错误? 例如,我想重构以下代码以避免嵌套错误:

.for_each(|record| {
    match f1() {
        Ok(a1) => match f2() {
            Ok(a2) => match f3() {
                Ok(_) => {}
                Err(e) => {
                    eprintln!("Error: {}", e);
                }
            },
            Err(e) => {
                eprintln!("Error: {}", e);
            }
        },
        Err(e) => {
            eprintln!("Error: {}", e);
        }
    };
    Ok(())
})

问题不是重复的,因为我有一个for_each运算符,这使我的情况复杂化。当我将?放入f2时,实际上收到以下错误:

the trait `std::convert::From<std::io::Error>` is not implemented for `grpcio::error::Error`

1 个答案:

答案 0 :(得分:2)

您可以使用and_then链接成功方案中的函数,并使用map_err映射错误。

就像这里,您可以将它们链接起来:

let result = f1().and_then(|_| {
    f2().and_then(|_| {
        f3().and_then(|_| {
            println!("All functions are succeed");
            Ok(())
        })
    })
});

如果发生错误,您将在此处使用result变量。

然后您可以使用if let Err(error)语句来匹配此错误,如下所示:

if let Err(error) = result {
    println!("Problem occurred: {:?}", error);
};

还可以使用try!宏或?运算符将错误提升到更高级别,如下所示:

fn throw_error() -> Result<String, MyError> {
    let string_val = "will not be returned".to_string();

    Err(MyError::thrownError)?;
    Ok(string_val)
}

Here,您可以测试并多玩一些以了解概念。