If statement 如何在Rust中传播错误?

If statement 如何在Rust中传播错误?,if-statement,rust,If Statement,Rust,是否有一种很好的方法来传播Rust中的错误? 例如,我想重构以下代码以避免嵌套错误: .for_each(|record| { match f1() { Ok(a1) => match f2() { Ok(a2) => match f3() { Ok(_) => {} Err(e) => { eprintln!("Erro

是否有一种很好的方法来传播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(())
})
这个问题不是重复的,因为我为每个操作符都设置了一个
,这使我的情况变得复杂。当我把
放到
f2
时,我实际上收到了以下错误:

the trait `std::convert::From<std::io::Error>` is not implemented for `grpcio::error::Error`
trait`std::convert::From`未为`grpcio::error::error'实现`

您可以在成功场景中使用
和_
链接您的函数,然后使用
映射_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);
};
fn throw_error() -> Result<String, MyError> {
    let string_val = "will not be returned".to_string();

    Err(MyError::thrownError)?;
    Ok(string_val)
}
也有可能通过
try将错误抛出到更高级别宏或
运算符,如下所示:

if let Err(error) = result {
    println!("Problem occurred: {:?}", error);
};
fn throw_error() -> Result<String, MyError> {
    let string_val = "will not be returned".to_string();

    Err(MyError::thrownError)?;
    Ok(string_val)
}
fn throw\u error()->结果{
let string_val=“将不会被返回”。to_string();
错误(MyError::thrownError)?;
Ok(字符串值)
}

您可以进行更多的测试和播放,以理解这些概念。

您可以在成功场景中使用
链接您的函数,然后使用
映射错误

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

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);
};
fn throw_error() -> Result<String, MyError> {
    let string_val = "will not be returned".to_string();

    Err(MyError::thrownError)?;
    Ok(string_val)
}
也有可能通过
try将错误抛出到更高级别宏或
运算符,如下所示:

if let Err(error) = result {
    println!("Problem occurred: {:?}", error);
};
fn throw_error() -> Result<String, MyError> {
    let string_val = "will not be returned".to_string();

    Err(MyError::thrownError)?;
    Ok(string_val)
}
fn throw\u error()->结果{
let string_val=“将不会被返回”。to_string();
错误(MyError::thrownError)?;
Ok(字符串值)
}

你可以多测试和玩一点来理解这些概念。

谢谢你的建议,可能会重复@hellow,但我不明白我是如何将
一起用于每个
。不要对每个
使用
,而是对循环使用经典:)f1、f2和f3是否具有相同的错误类型?不幸的是,你不能使用函数式循环+错误传播,因为你在一个闭包中。@hellow的可能重复谢谢你的建议,但我不明白我是如何将
一起用于每个
。不要对每个
使用
,但是循环的经典:)是f1,f2和f3具有相同的错误类型?不幸的是,您不能使用函数样式循环+错误传播,因为您在闭包中。