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

eik*_*iko 1 rust

我写了一个基于Rust文档的非常简单的脚本:

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!");
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

但我得到以下编译错误?:

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`
Run Code Online (Sandbox Code Playgroud)

我只是部分理解,?但我知道要点是,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());
    }

}
Run Code Online (Sandbox Code Playgroud)

但我得到错误:

error: no method named `path` found for type `std::fs::ReadDir` in the current scope
 --> test.rs:7:30
  |
7 |         println!("{}", entry.path());
  |                              ^^^^
Run Code Online (Sandbox Code Playgroud)

这意味着的而不是fs::read_dir返回ReadDir这比一个迭代DirEntry的项目,fs::read_dir正在恢复()其在某种程度上在一个迭代ReadDir的项目?

我很困惑.

值得一提的是我正在运行: rustc 1.16.0 (30cf806ef 2017-03-10)

She*_*ter 6

第一个错误是因为你不能使用try!?在函数返回().

第二个错误是因为read_dir返回一个Result:

pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir>
Run Code Online (Sandbox Code Playgroud)

Result实现IntoIterator,path实际上是你认为你拥有的迭代器.

处理错误和调用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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @asteriskTheServer`?`是*不是*糖围绕`try!`.如果它是; 使用任何一个都会得到同样的错误,目前情况并非如此.如果有的话,`try!`宏应该委托给`?`. (3认同)
  • @eiko我建议的主要资源是本书的[错误处理章节](https://doc.rust-lang.org/stable/book/error-handling.html).`try!`是传播错误的先前惯用方法,但```已在更新版本的Rust中取代它.`try!`仍然存在是出于向后兼容的原因. (2认同)

E_n*_*ate 5

?运营商和try!宏将当你的函数返回一个唯一的工作Result(其中出现的错误可以被正确地转换,当然)。main 函数不返回结果。

您可能希望将所有代码发送到一个单独的函数并处理 中的错误main(),如下所示:

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(())
}
Run Code Online (Sandbox Code Playgroud)