将文件名收集到“Vec<str>”中

vas*_*ily 1 rust

如何将目录中的文件名收集为以下内容Vec<&str>

let paths = fs::read_dir("...")
    .unwrap()
    .filter_map(|e| e.ok())
    .map(|e| e.path().to_str());
Run Code Online (Sandbox Code Playgroud)

另外,如果文件夹不存在,如何使其返回空列表?

har*_*mic 7

fs::read_dir返回一个迭代 的迭代器Result<DirEntry>,它公开一个DirEntry::path方法。此方法返回一个PathBuf,它拥有包含文件名的缓冲区。

在您的原始示例中,您尝试将它们转换为&str- 存在两个问题:

  1. path()返回 a PathBuf,您从中获取引用(通过to_str()),但您没有将其存储PathBuf在任何地方,因此编译失败并出现以下错误:
error[E0515]: cannot return value referencing temporary value
 --> src/main.rs:7:18
  |
7 |         .map(|e| e.path().to_str());
  |                  --------^^^^^^^^^
  |                  |
  |                  returns a value referencing data owned by the current function
  |                  temporary value created here
Run Code Online (Sandbox Code Playgroud)
  1. to_str()返回Option<str>- 如果 Path 包含任何非 UTF8 字符,则返回None。你最终会得到一个Vec包含的Option<&str>.

我建议将它们收集到一个Vec<PathBuf>,这很简单:

error[E0515]: cannot return value referencing temporary value
 --> src/main.rs:7:18
  |
7 |         .map(|e| e.path().to_str());
  |                  --------^^^^^^^^^
  |                  |
  |                  returns a value referencing data owned by the current function
  |                  temporary value created here
Run Code Online (Sandbox Code Playgroud)

如果您确实需要它们作为字符串,您可以使用:

    let paths = fs::read_dir("...")
        .unwrap()
        .filter_map(|e| e.ok())
        .map(|e| e.path())
        .collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

to_string_lossy()会将路径转换为字符串,并用替换字符替换任何非 utf8 字符。它返回一个Cow<&str>- ,它可能或可能不实际拥有该字符串。为了确保返回拥有的字符串,我们调用into_owned().

最后,如果文件夹不存在,要使其返回空列表,您可以使用如下内容:

    let paths = fs::read_dir("...")
        .unwrap()
        .filter_map(|e| e.ok())
        .map(|e| e.path().to_string_lossy().into_owned())
        .collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

如果发生任何其他错误,上面的示例将会出现恐慌NotFound- 实际上,您可能会更优雅地处理这种情况。