Давайте читать сообщения об ошибках компилятора вместе!
error: no method named `path` found for type `std::fs::ReadDir` in the current scope
--> src/main.rs:5:26
|
5 | let path = entry.path();
| ^^^^
Это означает, что тип entry
является ReadDir
, но как же это случилось? Предполагается, что мы будем перебирать ReadDir
!
Если мы посмотрим на documentation for read_dir
, мы можем видеть, что она возвращает Result
:
pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir>
Это означает, что процесс чтения каталога может потерпеть неудачу, что вполне правдоподобно - что, если каталог Безразлично» t существует? Однако представленный код не обрабатывает эту ошибку. Вместо этого он передает Result
в цикл for
. for
работает с помощью IntoIterator
и Result
, что дает Ok
случай или вообще ничего. Option
имеет аналогичную реализацию.
Итак, вы добавили try!
в код ...
for entry in try!(fs::read_dir("/etc"))
error[E0308]: mismatched types
--> src/main.rs:4:18
|
4 | for entry in try!(fs::read_dir("/etc")) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected(), found enum `std::result::Result`
|
= note: expected type `()`
= note: found type `std::result::Result<_, _>`
= note: this error originates in a macro outside of the current crate
Как уже discussed previously и упоминается в documentation for try!
:
Из-за раннего возвращения, try!
может использоваться только в функциях, которые возвращают Result
.
Вы должны обрабатывать ошибки как-то, и по какой-либо причине, текущая функция утверждает, что она не может не - это не возвращает Result
! Вместо этого давайте просто убить всю программу паниковать, добавляя expect
к вызову:
for entry in fs::read_dir("/etc").expect("I told you this directory exists")
(Некоторые люди используют unwrap
, но я буду всегда выступает за expect
как он имеет более высокую вероятность предоставления полезной информации для бедные души, которые испытывают возможный отказ)
error: no method named `path` found for type `std::result::Result<std::fs::DirEntry, std::io::Error>` in the current scope
--> src/main.rs:5:26
|
5 | let path = entry.path();
| ^^^^
Да, есть еще более Возможны случаи отказа. В частности, по какой-то причине чтение каждой записи может завершиться неудачей. Вот почему ReadDir
итератора говорит
type Item = Result<DirEntry>
Опять же, ваша функция по-прежнему утверждает, что не может потерпеть неудачу, поэтому мы должны паниковать снова:
let entry = entry.expect("I couldn't read something inside the directory");
error[E0277]: the trait bound `std::fs::DirEntry: std::fmt::Display` is not satisfied
--> src/main.rs:9:26
|
9 | print!("{}", entry);
| ^^^^^ trait `std::fs::DirEntry: std::fmt::Display` not satisfied
|
= note: `std::fs::DirEntry` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
= note: required by `std::fmt::Display::fmt`
Как указано также в ошибке сообщение, изменить {}
до {:?}
, потому что DirEntry
не имеет надлежащего способа форматирования для конечных пользователей. Программисты могут работать с форматом отладки.
use std::fs;
fn main() {
for entry in fs::read_dir("/etc").expect("I told you this directory exists") {
let entry = entry.expect("I couldn't read something inside the directory");
let path = entry.path();
if path.is_dir() {
print!("{:?}", entry);
}
}
}
Я настоятельно рекомендую перечитывая error handling chapter из The Rust Programming Language. Я также выступаю за то, чтобы в основном заучивать методы и черты, реализованные для Result
и Option
, видя, насколько ядром для них является опыт Rust.
Вот версия, которая возвращает ошибку и использует оператор горячей вне-пресс TRY (?
):
use std::fs;
use std::error::Error;
fn inner_main() -> Result<(), Box<Error>> {
for entry in fs::read_dir("/etc")? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
print!("{:?}", entry);
}
}
Ok(())
}
fn main() {
inner_main().expect("Unable to process");
}
Примечание: с помощью 'попробовать' макрос, или так как вы на 1.13 Оператор '?' требует функции, в которой он вызывается, чтобы вернуть «Результат»; это то, что 'ожидаемый(), найденный enum ...' говорит вам. –
@Shepmaster: Если я получаю это право, 'read_dir' возвращает результат, который реализует' IntoIterator', приводящий к фактическому экземпляру 'ReadDir', который выполняет ИИ вместо записей каталога. –
@ MatthieuM. yep – Shepmaster