如何过滤文件路径,然后使用生成的路径

时间:2015-05-28 19:37:08

标签: file file-io rust filepath

我试图从目录中获取mp3列表。

let dir_paths = fs::read_dir(&Path::new("some_directory")).unwrap();

let paths = dir_paths.filter(|x| match x.unwrap().path().extension() {
    None => true,
    Some(ext) => ext == "mp3"
});

错误讯息

src/main.rs:27:48: 27:49 error: cannot move out of borrowed content
src/main.rs:27     let paths = dir_paths.filter(|ref x| match x.unwrap().path().extension() {
                                                              ^

我尝试用|x|替换|ref x|,但收到了相同的错误消息。这样做的正确方法是什么

1 个答案:

答案 0 :(得分:4)

我们来看看Result::unwrap的文档:

fn unwrap(self) -> T
     

展开结果,产生Ok的内容。

请注意self如何?这意味着该选项将被消耗。但是,您的迭代器正在将闭包传递给&Result<T, _>。您无法取得Option的所有权,因为它是借用的。

最短的解决方法是使用as_ref来获取Result<&T, _>

use std::fs;

fn main() {
    let dir_paths = fs::read_dir("/").unwrap();

    let paths = dir_paths.filter(|x| match x.as_ref().unwrap().path().extension() {
        None => true,
        Some(ext) => ext == "mp3"
    });
}

虽然我可能选择将其写为

use std::fs;
use std::ffi::OsStr;

fn main() {
    let dir_paths = fs::read_dir("/").unwrap();

    dir_paths
        .filter_map(|x| x.ok())
        .filter(|x| x.path().extension().and_then(OsStr::to_str) == Some("mp3"));
}

有一些不那么展开 - 我们只是忽略任何失败的DirEntry。这取决于你的错误处理策略。