迭代std :: fs :: ReadDir并仅从路径获取文件名

Syn*_*ose 12 rust

我正在试图弄清楚如何用锈蚀做一个'列表理解'.我有一个ReadDir想要映射的iter,只获取路径的文件名.我觉得它看起来像是这样的:

// get current dir paths
let paths = fs::read_dir(&Path::new(
    &env::current_dir().unwrap())).unwrap();

// should contain only filenames
let files_names = paths.map(|&x| {
    match (*x).extensions() {
        Some(y) => y,
        None => //What do I do here? break?
};
Run Code Online (Sandbox Code Playgroud)

我知道我的表情很可能会被破坏,但有没有办法让这个表达能够与我绑定file_names

Jor*_*eña 22

您可能想要使用生成文件名Pathfile_name()方法(如果它是常规文件),这就是它返回的原因Option.

我想你想要忽略不是常规文件的文件名,也就是那些file_name()会返回的文件名None,在这种情况下你可能想要利用Iteratorfilter_map方法基本上就像过滤器和地图放在一起,即你'能够映射(在这种情况下是路径 - >文件名)并通过将映射结果作为a 来过滤Option,其中None表示您要过滤掉该值.

令人烦恼的是你必须检查ReadDir迭代器返回的每个项目,因为那是一个Result类型,所以你必须看看它是否是Ok.如果您只想忽略目录中的非Ok(即Err)条目(例如,您没有权限的条目),您只需将其转换为Option使用Resultok()方法并将其集成到filter_map.

您还必须尝试String从返回中创建一个file_name(),因为它可能不一定是UTF-8.与非UTF-8名的文件可以简单地再次使用的组合被忽略(在这个例子中)mapand_then.

下面是它会是什么样如果你把它忽略不喜欢Ok目录条目和路径不属于常规文件(从而返回Nonefile_name()),以及文件,其文件名不是UTF-8:

let paths = fs::read_dir(&Path::new(
  &env::current_dir().unwrap())).unwrap();

let names =
paths.filter_map(|entry| {
  entry.ok().and_then(|e|
    e.path().file_name()
    .and_then(|n| n.to_str().map(|s| String::from(s)))
  )
}).collect::<Vec<String>>();
Run Code Online (Sandbox Code Playgroud)

围栏

如果你不是很熟悉,防锈的功能的流量控制功能,例如map,and_then等上ResultOption,然后在这里是它会是什么样子向外扩张,而不会忽略错误并没有做错误处理.我把它留给你:

let paths = fs::read_dir(&Path::new(
  &env::current_dir().unwrap())).unwrap();

let names =
paths.map(|entry| {
  let entry = entry.unwrap();

  let entry_path = entry.path();

  let file_name = entry_path.file_name().unwrap();

  let file_name_as_str = file_name.to_str().unwrap();

  let file_name_as_string = String::from(file_name_as_str);

  file_name_as_string
}).collect::<Vec<String>>();
Run Code Online (Sandbox Code Playgroud)

围栏