首页 > 解决方案 > 我是否应该放弃使用 `and_then` 并始终使用 `?` 运算符?

问题描述

我想写这样的东西,但由于类型之间的不匹配而无法编译:

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let val = std::env::args()
        .nth(1)
        .ok_or("1 arg is expected")
        .and_then(std::fs::File::open)
        .and_then(serde_yaml::from_reader)?;
}

因为map_err在每个闭包中添加 a 看起来很慢并且“锅炉板”,所以我将其替换为以下内容:

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let val = serde_yaml::from_reader(std::fs::File::open(
        std::env::args().nth(1).ok_or("1 arg is expected")?,
    )?)?;
}

第一个感觉更自然,读起来像英语,而第二个感觉有点倒退。

我应该放弃and_then并始终使用?操作员吗?

如果没有,有没有办法让结果组合器像?运算符一样平滑?

标签: error-handlingrustrust-result

解决方案


我应该放弃 and_then 并始终使用 吗?操作员 ?

这是个人判断,只有你能回答。

有没有办法让结果组合器像 ? 操作员 ?

坦白说没有。?“隐式”执行转换(不是真正隐式,因为它是其工作的很大一部分,但不必单独调用转换,也许“简洁”?),and_then没有。这意味着在使用时and_then,您必须自己执行这些转换。这似乎合乎逻辑。

您也许可以为此构建一个方便的宏。或者可能添加一个扩展方法或包装器类型,可以在后台执行这些转换。


推荐阅读