我根据Rust docs编写了一个非常简单的脚本:
use std::fs::{self, DirEntry};
use std::path::Path;
fn main() {
let path = Path::new(".");
for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
println!("directory found!");
}
}
}
但是我收到了关于?
的以下编译错误:
error[E0277]: the trait bound `(): std::ops::Carrier` is not satisfied
--> test.rs:6:18
|
6 | for entry in fs::read_dir(path)? {
| -------------------
| |
| the trait `std::ops::Carrier` is not implemented for `()`
| in this macro invocation
|
= note: required by `std::ops::Carrier::from_error`
error[E0277]: the trait bound `(): std::ops::Carrier` is not satisfied
--> test.rs:7:21
|
7 | let entry = entry?;
| ------
| |
| the trait `std::ops::Carrier` is not implemented for `()`
| in this macro invocation
|
= note: required by `std::ops::Carrier::from_error`
我只是部分理解?
,但我知道要点是,只有当Result
时,才允许您对Ok
采取行动。这里的错误是它被用在()
而不是Result
上,这很奇怪。我尝试在没有?
的情况下实现循环:
use std::fs::{self, DirEntry};
use std::path::Path;
fn main() {
let path = Path::new(".");
for entry in fs::read_dir(path) {
println!("{}", entry.path());
}
}
但我收到错误:
error: no method named `path` found for type `std::fs::ReadDir` in the current scope
--> test.rs:7:30
|
7 | println!("{}", entry.path());
| ^^^^
这意味着fs::read_dir
不是ReadDir
返回DirEntry
而是fs::read_dir
项上的迭代器,而()
正在返回ReadDir
,它在某种程度上是{的迭代器{1}}项?
我很困惑。
值得一提的是,我正在运行:rustc 1.16.0 (30cf806ef 2017-03-10)
答案 0 :(得分:5)
第一个错误是because you cannot use try!
or ?
in a function returning ()
。
第二个错误是因为read_dir
返回Result
:
pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir>
Result
implements IntoIterator
,所以path
实际上是你认为的迭代器。
Handling the errors并致电Path::display
为您提供所需内容:
use std::fs;
use std::path::Path;
fn main() {
let path = Path::new(".");
for entry in fs::read_dir(path).expect("Unable to list") {
let entry = entry.expect("unable to get entry");
println!("{}", entry.path().display());
}
}
答案 1 :(得分:4)
The ?
operator and the try!
macro will only work when your function returns a Result
(in which the raised errors can be properly converted, of course). The main function does not return a result.
You may wish to send all of your code to a separate function and handle the error in main()
, with something like this:
use std::io;
use std::fs::{self, DirEntry};
use std::path::Path;
fn main() {
run().unwrap_or_else(|e| {
println!("Something went wrong: {}", e.to_string());
});
}
fn run() -> io::Result<()> {
let path = Path::new(".");
for entry in fs::read_dir(path)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
println!("directory found!");
}
}
Ok(())
}