2015-02-05 48 views
3

我試圖列出目錄中的文件,然後將文件名複製到我自己的Vec中。我嘗試了幾種解決方案,但總是以無法創建足夠長的生活變量爲題。我不明白我的錯誤。創建Vec時借用的值不夠長住

fn getList(action_dir_path : &str) -> Vec<&str> { 
    let v = fs::readdir(&Path::new(action_dir_path)) 
      .unwrap() 
      .iter() 
      .map(|&x| x.filestem_str().unwrap()) 
      .collect(); 
    return v; 
} 

我想知道爲什麼編譯器會抱怨「x」?我不在乎x,我想要它裏面的& str,我認爲& str是靜態的。

我試過這種方式,但是我得到了與抱怨「路徑」不夠長的編譯器相同的結果。

fn getList2(action_dir_path : &str) -> Vec<&str> { 
    let paths = fs::readdir(&Path::new(action_dir_path)).unwrap(); 
    let mut v : Vec<&str> = Vec::new(); 

    for path in paths.iter(){ 
     let aSlice = path.filestem_str().unwrap(); 
     v.push(aSlice); 
    } 

    return v; 
} 

這裏的圍欄:http://is.gd/4FajDs

回答

6

的問題來自filestem_str。這是簽名:

fn filestem_str<'a>(&'a self) -> Option<&'a str> 

這表明,該方法將一個借來參考返回一個字符串Path結構是該字符串的所有者。當你離開該方法時,沒有任何地方擁有Path,所以它將被丟棄。這意味着對Path的任何引用將不再有效。這是Rust防止你引用不再分配的內存,對於Rust是好的!

您可以做的最簡單的事情是返回一個Vec<String>String擁有它裏面的字符串,所以我們並不需要擔心它被釋放,當我們離開的功能:(!不收費)

fn get_list(action_dir_path: &str) -> Vec<String> { 
    fs::readdir(&Path::new(action_dir_path)) 
     .unwrap() 
     .iter() 
     .map(|x| x.filestem_str().unwrap().to_string()) 
     .collect() 
} 

我也更新了風格更加鏽狀。對於項目使用snake_case,在類型定義中的冒號前沒有空格,並且沒有理由設置一個變量來返回它。此外,不要使用明確的return語句,除非您提前退出函數。

+0

謝謝你的回答,我現在明白了! thx也爲您的免費更正和建議! – mrburne 2015-02-05 22:38:40

0

一個小有關的話:

我以爲&海峽是靜態的。

&'static str s是靜態的,但這只是一種&str。它可以有任何一種生命。

+0

是的你是對的。我在鏽書http://doc.rust-lang.org/book/more-strings.html有關字符串字面量的討論中誤解了&amp; str。 – mrburne 2015-02-06 09:32:15

相關問題