Error handling 用组合子简化匹配

Error handling 用组合子简化匹配,error-handling,rust,pattern-matching,Error Handling,Rust,Pattern Matching,我有这样的想法: match fnX( fnY(x), // Returns Result<(), X> ) // Returns Result<(), Y> .await { Ok(v) => { if v.is_err() { error!("error = {}", v); } } Err(e) => error!("error = {}", e), }; 匹配fn

我有这样的想法:

match fnX(
    fnY(x), // Returns Result<(), X>
) // Returns Result<(), Y>
.await
{
    Ok(v) => {
        if v.is_err() {
            error!("error = {}", v);
        }
    }
    Err(e) => error!("error = {}", e),
};
匹配fnX(
fnY(x),//返回结果
)//返回结果
.等待
{
Ok(v)=>{
如果v.is_err(){
错误!(“错误={}”,v);
}
}
Err(e)=>error!(“error={}”,e),
};
如何使用组合器编写此代码,以便只需
出错一次?我不想对
Ok
值执行任何操作,只需打印错误,无论它来自
fnX
还是
fnY
,您不需要这样的“组合器”

fnX
接受类型为
Result
的参数,并返回
Result

当代码被卷积时,它可能有助于分离表达式,使其更具可读性

let result = fnY(x);
match fnX(result).await {
    Ok(v) => {
        // here v is ok value, in this case ()
    }
    Err(e) => error!("error = {}", e),
};

我假设您打算简化类似的内容(删除与问题无关的
.wait
):

如果错误类型不同,可以使用将其转换为单个类型:

match fnX(x)
    .map_err(MyError::from)
    .and_then(|y| fnY(y).map_err(MyError::from))
{
    Ok(_) => println!("Success!"),
    Err(e) => error!("error = {}", e),
}
后者可以使用板条箱的最新开发版本进行简化:

match map\u for!(y println!(“成功”),
Err(e@MyError{..})=>error!(“error={}”,e),
}
  • 请注意,只有当编译器无法自动推断错误类型时,才需要
    @MyError{..}
    注释
  • 完整免责声明:我是
板条箱的
地图的作者

期望值真的不清楚,你怎么可能从一个返回
结果的函数中得到
v.is_err()
?这毫无意义,根据定义
v
将是
()
没有
是错误的。
fnX()
真的将
结果作为输入吗?
match fnX(x).and_then(fnY) {
    Ok(_) => println!("Success!"),
    Err(e) => error!("error = {}", e),
}
match fnX(x)
    .map_err(MyError::from)
    .and_then(|y| fnY(y).map_err(MyError::from))
{
    Ok(_) => println!("Success!"),
    Err(e) => error!("error = {}", e),
}
match map_for!(y <- fnX (x);
               v <- fnY (y);
               => v)
{
    Ok(_) => println!("Success"),
    Err(e @ MyError { .. }) => error!("error = {}", e),
}