Deep Rust 匹配:有更好的方法吗?
Deep Rust matching: is there a better way?
我刚刚发现自己在写这个:
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。
您正在寻找专为此任务而设计的 ?
operator。
foo()?
相当于
match foo() {
Ok(t) => t
Err(e) => return Err(e.into()),
}
因此,您可以在 return 是 Try
实现的任何内容的末尾添加 ?
。您必须使您的函数 return Result<(), E>
,但这也无妨,因为这样您的函数将报告其错误,而不是默默地失败。
我刚刚发现自己在写这个:
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。
您正在寻找专为此任务而设计的 ?
operator。
foo()?
相当于
match foo() {
Ok(t) => t
Err(e) => return Err(e.into()),
}
因此,您可以在 return 是 Try
实现的任何内容的末尾添加 ?
。您必须使您的函数 return Result<(), E>
,但这也无妨,因为这样您的函数将报告其错误,而不是默默地失败。