Ответ 1
Вероятно, вы захотите использовать метод Path
file_name()
, который дает имя файла, если он является обычным файлом, поэтому он возвращает Option
.
Я предполагаю, что вы хотите игнорировать имена файлов, которые не являются обычными файлами, то есть для которых file_name()
вернет None
, и в этом случае вы, вероятно, захотите использовать Iterator
filter_map
метод, который в основном похож на фильтр и карту, собранные вместе, то есть вы можете сопоставить (в данном случае путь → имя файла) и фильтровать, возвращая отображаемый результат как Option
, где None
означает, что вы хотите отфильтровать это значение.
Досадно, что вам нужно проверить каждый элемент, возвращенный итератором ReadDir
, так как это тип Result
, поэтому вам нужно будет увидеть, есть ли он Ok
. Если вы просто хотите игнорировать записи не Ok
(т.е. Err
) в каталоге (например, записи, для которых у вас нет разрешения), вы можете просто преобразовать их в Option
с помощью Result
ok()
и интегрируйте это в filter_map
.
Вам также придется попытаться создать String
из возвращаемого file_name()
, так как это может быть не обязательно UTF-8. Файлы с именами, отличными от UTF-8, можно просто проигнорировать (в этом примере) снова, используя комбинацию map
и and_then
.
Вот как это выглядело бы, если бы вы проигнорировали записи и пути к каталогу не Ok
, которые не являются обычными файлами (и, таким образом, возвращают None
на file_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>>();
Если вы не очень хорошо знакомы с функциональными функциями управления потоком Rust, например. map
, and_then
и т.д. на Result
и Option
, то вот что бы оно выглядело как расширенное, без игнорирования ошибок и без обработки ошибок. Я оставляю это до вас:
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>>();