2017-04-13 124 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(()) 
} 
相關問題