2015-05-28 3 views
2

Я пытаюсь получить список 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| но получил то же самое сообщение об ошибке. Что такое правильный способ сделать это

ответ

4

Давайте посмотрим на документацию для Result::unwrap:

fn unwrap(self) -> T 

разворачивает результат, получая содержание ОК.

Примечание: self? Это означает, что этот вариант будет использован. Тем не менее, ваш итератор проходит закрытие &Result<T, _>. Вы не можете взять на себя ответственность за Option, потому что он заимствован.

Кратчайший исправление получить Result<&T, _> вместо этого, используя as_ref:

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 s. Однако это зависит от вашей стратегии обработки ошибок.

+0

Ваша версия намного приятнее –

Смежные вопросы