2017-04-13 125 views
0

我已经写了基于该Rust docs一个非常直接的脚本:如何访问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!"); 
     } 
    } 

} 

,但我得到以下编译错误约?

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` 

我只是部分了解?但我知道要点是,它只有在Ok的情况下才允许你在Result上采取行动。这里的错误是它在()而不是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项目?

我很困惑。

这也许值得一提的是,我快:rustc 1.16.0 (30cf806ef 2017-03-10)

+0

你会发现这个没有在目录中访问的文件都做:在文档,代码不是内部'的main() '。 –

回答

4

第一个错误是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()); 
    } 
} 
+0

谢谢!这回答了这个问题,让我说我只是部分理解了'?'(这个问题是“当*的值不是'Ok'时'做什么'?)。是否有我错过的资源? ''和'try!'在锈书中没有提到,但是文档似乎假定它的共同知识。 – eiko

+1

@eiko http://rustbyexample.com/std/result/try.html。?运算符只是糖周围尝试!所以它应该抛出一个关于该类型的编译错误,如果它不是结果。 – asteriskTheServer

+2

@eiko我建议的主要资源是[错误处理章节](https:// doc。这本书的“rust-lang.org/stable/book/error-handling.html”)。'是以前用于传播错误的惯用方式,但'?'已经在更新版本的Rust中取代了它。为了向后兼容的原因,“try!”仍然存在。 – Shepmaster

4

?操作,当你的函数返回一个Result(其中出现的错误可以被正确地转换,当然)的try!宏才有效。主函数不返回结果。

您可能希望所有的代码发送到一个单独的功能和处理错误的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(()) 
} 
相关问题