【问题标题】:Deep Rust matching: is there a better way?深度 Rust 匹配:有更好的方法吗?
【发布时间】:2019-11-05 07:06:51
【问题描述】:

我刚刚发现自己在写这个:

fn init_timestamps(dir: &PathBuf, file_timestamps: &'static HashMap<PathBuf,Duration>) {

    match fs::read_dir(dir) {
        Ok(iter) => iter.for_each(|result| match result {
            Ok(entry)  => {
                if entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
                    init_timestamps(&entry.path(), file_timestamps);
                } else {
                    match entry.metadata() {
                        Ok(md) => match md.modified() {
                            Ok(modified) => {
                                locked_timestamps.insert(entry.path(), modified.duration_since(SystemTime::UNIX_EPOCH).unwrap());
                            },
                            Err(_) => ()
                        },
                        Err(_) => ()
                    };
                }
            },
            Err(_) => ()
        }),
        Err(_) => ()
    };
}

我不得不问:我还缺少更好的模式吗?我尝试在每个级别使用.map(),这看起来稍微好一些,但给了我关于未使用结果的编译器警告。在这种一般情况下,我想要做的是“如果这条结果链(或选项)一直存在,则执行 X。否则,什么也不做。”我也遇到过类似的情况,我想将链中的“失败”点强制为false(在最完整的深度有一个布尔检查)。

这实际上可以看作是 Rust 版本的空检查问题,使用其他语言中的空合并运算符 such as Kotlin 解决。

【问题讨论】:

    标签: rust idioms


    【解决方案1】:

    您正在寻找专为这项任务而设计的? operator

    foo()?
    

    等价于

    match foo() {
        Ok(t)  => t
        Err(e) => return Err(e.into()),
    }
    

    所以你可以在任何返回Try 实现的东西的末尾抛出?。你必须让你的函数返回Result&lt;(), E&gt;,但这也很好,因为这样你的函数会报告它的错误而不是静默失败。

    【讨论】:

    • 哇!我不敢相信直到现在我还没有遇到过。仍在尝试弄清楚如何在使编译器满意的同时使用它,但理论上它似乎正是我想要的。
    猜你喜欢
    • 2017-11-03
    • 2013-04-04
    • 2013-09-23
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 2017-11-07
    • 2019-08-15
    • 1970-01-01
    相关资源
    最近更新 更多