2014-09-19 101 views
2

我想讀取並行目錄中的文件的內容。我遇到了終生問題。如何解決此生鏽問題?

我的代碼如下所示:

use std::io::fs; 
use std::io; 
use std::collections::HashMap; 
use std::comm; 
use std::io::File; 

fn main() { 
    let (tx, rx) = comm::channel(); // (Sender, Receiver) 

    let paths = fs::readdir(&Path::new("resources/tests")).unwrap(); 

    for path in paths.iter() { 
     let task_tx = tx.clone(); 

     spawn(proc() { 
      match File::open(path).read_to_end() { 
       Ok(data) => task_tx.send((path.filename_str().unwrap(), data)), 
       Err(e) => fail!("Could not read one of the files! Error: {}", e) 
      }; 
     }); 
    } 

    let mut results = HashMap::new(); 

    for _ in range(0, paths.len()) { 
     let (filename, data) = rx.recv(); 

     results.insert(filename, data); 
    } 

    println!("{}", results); 
} 

我得到的編譯錯誤是:

error: paths does not live long enough

note: reference must be valid for the static lifetime...

note: ...but borrowed value is only valid for the block at 7:19

我也試過在循環使用into_iter()(或move_iter()之前)沒有成功。

我懷疑它與產生的任務在整個main()範圍之外仍然存在,但我不知道如何解決這種情況。

回答

4

錯誤消息可能有點令人困惑,但它告訴你的是,你正試圖在任務中使用參考path。 由於spawn使用的是proc,因此您只能使用可以將所有權轉讓給該任務的數據(Send類型)。

要解決,你可以做到這一點(你可以使用一個move_iter但你不能在循環之後訪問路徑):

for path in paths.iter() { 
    let task_tx = tx.clone(); 

    let p = path.clone(); 
    spawn(proc() { 
     match File::open(&p).read_to_end() { 

的第二個問題是,你要發送&str(文件名)通過一個頻道。與任務類型相同,必須是種類Send

match File::open(&p).read_to_end() { 
     Ok(data) => task_tx.send((p.filename_str().unwrap().to_string(), data)), 
     Err(e) => fail!("Could not read one of the files! Error: {}", e) 
    };