此代码打印一对 Ok
在我的系统上:
use std::fs;
fn main() {
fs::read_dir("/home").unwrap().for_each(|e| {
println!("{:?}", e);
});
}
我需要unwrap
DirEntry
使用它们之前的元素。
fs::read_dir
的文档状态:
Returns an iterator over the entries within a directory.
The iterator will yield instances of
io::Result<DirEntry>
. New errors may be encountered after an iterator is initially constructed.
文档中提到的错误类型是什么? unwrap
安全吗Result
?
最佳答案
fs::read_dir
打开目录时可能会遇到错误,例如目录不存在或用户没有读取权限。但是,即使在打开目录后,也可能会出现任意数量的错误:
- 该目录可能已被删除;
- 目录的权限可能已经改变;
- 底层存储介质可能有 IO 错误(例如硬盘驱动器故障);
- 该目录可以位于已移除的可移动驱动器上(或已断开连接的网络驱动器);
- 或操作系统可能为操作提供的任何其他错误
不可能在 fs::read_dir
给出的结果中返回此错误;相反,我们必须在迭代器本身中提供它们。这就是迭代器产生 Result<DirEntry, std::io::Error>
类型项的原因,以便程序员有可能捕获并处理这些错误。
至于是否安全unwrap
结果,只有当你确定结果不是错误时,它才是真正安全的(否则你的代码会崩溃)。在许多情况下,例如在制作原型(prototype)时,您可能不关心代码是否崩溃,但是在用 Rust 编写适当的应用程序时,您应该避免 unwrap
而是依赖于正确的错误处理和错误传播。
这是我在使用可能产生错误的迭代器时通常使用的模式:
use std::{fs, io};
fn read_dir_and_do_stuff() -> Result<(), io::Error> {
for entry in fs::read_dir("/home")? {
// ^
// v------------'--- automatically return errors
let entry = entry?;
// ... do something
println!("{:?}", entry);
}
Ok(())
}
fn main() {
if let Err(err) = read_dir_and_do_stuff() {
// handle error
println!("Error occurred: {}", err);
return;
}
}
您也可以使用 Iterator::try_fold
等方法, Iterator::try_for_each
和 Iterator::collect::<Result<..., E>>
如果你想使用链接而不是 for in
.
关于error-handling - 为什么 fs::read_dir() 在 Result<DirEntry, Error> 上返回一个迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59590497/