error-handling - 为什么 fs::read_dir() 在 Result<DirEntry, Error> 上返回一个迭代器

标签 error-handling rust

此代码打印一对 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/

相关文章:

java - Android Studio 未显示内联错误

java - 开始时带有按钮的布局

google-app-engine - 如何设置全局 DeadlineExceededError 处理程序?

c - 基本 C 程序已停止工作 : just in time debugger

docker - 编译 azure iot edge 的 edgelet 模块时出现 cargo 错误

rust - Tokio 的简单 TCP 回显服务器示例(在 GitHub 和 API 引用上)有什么好的详细解释?

vector - 为什么我不能借用盒装矢量内容作为可变内容?

rust - 如何复制 &[u8] 切片?

macros - 如何在宏中命名任意序列的事物?

php - 如何显示 PHP 错误?