如何访问Rust目录中的文件?

时间:2017-04-13 14:46:12

标签: rust

我根据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)

2 个答案:

答案 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(())
}