Deep Rust匹配:有更好的方法吗?

时间:2019-06-23 00:52:27

标签: rust idioms

我刚刚发现自己在写这篇文章:

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的null检查问题的版本,使用其他语言(?.https://kotlinlang.org/docs/reference/null-safety.html#safe-calls

解决了null算术运算符

1 个答案:

答案 0 :(得分:5)

您正在寻找专门用于完成此任务的? operator

foo()?

等同于

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

因此,您可以在返回?实现的所有内容的末尾抛出Try。您必须使函数返回Result<(), E>,但这也一样,因为那样您的函数将报告错误而不是无提示地失败。