【问题标题】:Rust returning a vector of pathbufs from a function after using fs::read_dirRust 在使用 fs::read_dir 后从函数返回一个 pathbufs 向量
【发布时间】:2024-04-20 04:35:02
【问题描述】:

嗨,我在这里找到了一些代码,似乎可以从函数返回 Vec,但我无法理解代码。代码如下,我添加了 cmets 以显示我在哪里感到困惑。

fn read_filename_from_dir<P>(path: P) -> Result<Vec<PathBuf>, io::Error> where P: AsRef<Path>,{
   fs::read_dir(path)? //returns result<readDir> ? unwraps to readDir
   .into_iter() //creates a new iter containing result<DirEntry> 
   .map(|x| x.map(|entry| entry.path()))
   .collect()  //the double map confuses me. this is where i lose understanding
}

我假设既然我们有一个包含 Result 的迭代器,我们是否必须首先解开每个 DirEntry 然后只映射一次解包,或者双映射是否以某种方式解包? 你将如何解开结果的迭代?使用 map(|x| x.unwrap()) ?

【问题讨论】:

    标签: rust file-io iterator unwrap


    【解决方案1】:

    第一张地图解压io::Result&lt;DirEntry&gt;。 read_dir 是一个惰性迭代器,因此它不会立即返回错误,但只有在您尝试通过开始迭代来读取目录之后。它还可以对前几个条目返回 Ok,然后返回 Err。

    内部映射将 DirEntry 转换为 PathBuf。

    下面是你可以用类型重写它的方法:

       .map(|entry_result: io::Result<DirEntry>| -> io::Result<PathBuf> {
           entry_result.map(|entry: DirEntry| -> PathBuf {
               entry.path()
           })
       })
    

    collect() 也很神奇,因为它不仅构建了一个 Vec,而且在第一个 Err 上也发生了短路,而不是返回 Vec&lt;io::Result&lt;PathBuf&gt;&gt;,它实际上返回了 io::Result&lt;Vec&lt;PathBuf&gt;&gt;。此行为特定于具有 Result 的迭代器。有一个example of this behaviour in the docs

    你可以在命令模式下重写相同的部分:

        let mut paths = Vec::<PathBuf>::new();
        for entry_result in fs::read_dir(path)? {
            let entry = entry_result?;
            paths.push(entry.path());
        }
        Ok(paths)
    

    它不再长了,但对更广泛的受众来说更简单易读。

    【讨论】: