在 Rust 中使用 and_then 有条件地对特定错误采取行动
Conditionally Acting on Specific Error Using and_then in Rust
我如何知道在 Rust 中通过 and_then
管道 Result
s 时发生了什么错误?例如,使用嵌套匹配我可以这样做:
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),
}
}
或者我可以使用 and_then
将第一个函数的结果通过管道传递给第二个并避免嵌套匹配:
match get_num(1).and_then(add_one) {
Ok(n) => println!("Adding one gives us: {}", n),
Err(why) => println!("Some error: {}.", why)
}
如何使用 and_then
有条件地和惯用地确定第二种形式中的错误?我必须键入检查错误吗?当然,我可以像上面那样显示错误,但假设我想在它前面加上与错误类型相关的内容?
通常的方法是使用 map_err
将初始错误转换为您可以控制的更丰富的错误,例如
enum MyError {
Parsing,
Adding
}
get_num(1).map_err(|_| MyError::Parsing)
.and_then(|v| add_one(v).map_err(|_| MyError::Adding)
遗憾的是,如您所见,这需要为 and_then
回调使用 lambda:and_then
必须 return 与输入的错误类型相同,因此这里它必须产生一个Result<_, MyError>
,wjhich 不是 add_one
的 return 类型。
虽然在其他情况下我们可以使用 ?
进行一些恢复,但这里相同的原始错误 type 被拆分为两个不同的值。
我如何知道在 Rust 中通过 and_then
管道 Result
s 时发生了什么错误?例如,使用嵌套匹配我可以这样做:
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),
}
}
或者我可以使用 and_then
将第一个函数的结果通过管道传递给第二个并避免嵌套匹配:
match get_num(1).and_then(add_one) {
Ok(n) => println!("Adding one gives us: {}", n),
Err(why) => println!("Some error: {}.", why)
}
如何使用 and_then
有条件地和惯用地确定第二种形式中的错误?我必须键入检查错误吗?当然,我可以像上面那样显示错误,但假设我想在它前面加上与错误类型相关的内容?
通常的方法是使用 map_err
将初始错误转换为您可以控制的更丰富的错误,例如
enum MyError {
Parsing,
Adding
}
get_num(1).map_err(|_| MyError::Parsing)
.and_then(|v| add_one(v).map_err(|_| MyError::Adding)
遗憾的是,如您所见,这需要为 and_then
回调使用 lambda:and_then
必须 return 与输入的错误类型相同,因此这里它必须产生一个Result<_, MyError>
,wjhich 不是 add_one
的 return 类型。
虽然在其他情况下我们可以使用 ?
进行一些恢复,但这里相同的原始错误 type 被拆分为两个不同的值。