有没有一种很好的方法可以在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`
答案 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,您可以测试并多玩一些以了解概念。