В процессе обучения Rust я знакомлюсь с распространением ошибок и выбором между unwrap
и оператором ?
. После написания кода прототипа, который использует только unwrap()
, я хотел бы удалить unwrap
из частей многократного использования, где паника на каждой ошибке неуместна.Альтернатива оператору try (?), Подходящему для отображения итератора
Как избежать использования unwrap
в закрытии, как в этом примере?
// todo is VecDeque<PathBuf>
let dir = fs::read_dir(&filename).unwrap();
todo.extend(dir.map(|dirent| dirent.unwrap().path()));
Первый unwrap
может быть легко изменен на ?
, до тех пор, пока функция возвращает содержащий Result<(), io::Error>
или аналогичный. Однако второй unwrap
, тот, который находится в dirent.unwrap().path()
, не может быть изменен на dirent?.path()
, поскольку закрытие должно вернуть PathBuf
, а не Result<PathBuf, io::Error>
.
Одним из вариантов является изменение extend
к явному цикла:
let dir = fs::read_dir(&filename)?;
for dirent in dir {
todo.push_back(dirent?.path());
}
Но что чувствует себя неправильно - оригинальный extend
элегантна и четко отражено намерение кода. (Возможно, он был более эффективным, чем последовательность push_back
.) Как опытный разработчик Rust выражает ошибку в таком коде?
Хорошие вопросы; Я не хотел упоминать конкретные примеры использования, чтобы избежать слишком долгого вопроса. В частности, я хотел бы сообщить все сбои и продолжить обработку. Например. рассмотрите функцию, которая подсчитывает файлы в подкаталогах ([python] (http://pastebin.com/XvzYZbsM)). [Ржавчина версия] (http://pastebin.com/HFKHq54T) паники при каждой ошибке, и я хотел бы, чтобы он регистрировал ошибку на stderr и продолжал подсчет, как это делает Python. – user4815162342
@ user4815162342: В этом случае вам понадобится сопоставление шаблонов в цикле 'for' и добавление к коллекции' PathBuf' для обработки, а другое из 'Error' для проблем. –
'filter_map (Результат: ok)' довольно аккуратно, спасибо. – user4815162342