2014-11-21 70 views
1

我想打開一個文件,替換一些字符,並進行一些拆分。然後我想返回字符串列表。但我得到error: broken does not live long enough。我的代碼在main中運行,所以它只是生命週期中的一個問題。終身不夠久生鏽

fn tokenize<'r>(fp: &'r str) -> Vec<&'r str> { 
    let data = match File::open(&Path::new(fp)).read_to_string(){ 
     Ok(n) => n, 
     Err(e) => fail!("couldn't read file: {}", e.desc) 
    }; 
    let broken = data.replace("'", " ' ").replace("\"", " \" ").replace(" ", " "); 
    let mut tokens = vec![]; 

    for t in broken.as_slice().split_str(" ").filter(|&x| *x != "\n"){ 
     tokens.push(t) 
    } 
    return tokens; 
} 

我怎樣才能讓這個函數返回的值生存在調用者的範圍內?

回答

3

問題是你的函數簽名說「結果與輸入fp的生命週期相同」,但事實並非如此。結果包含對您的函數內部分配的data的引用;它與fp無關!就目前而言,data將在您的函數結束時停止存在。

因爲您正在有效地創建新值,所以無法返回引用;您需要將該數據的所有權轉移出該功能。有兩種方法我能想到的要做到這一點,把我的頭頂部:

  1. ,而不是返回Vec<&str>,迴歸Vec<String>,其中每個令牌是新分配的字符串。

  2. 返回data在實現分裂邏輯的包裝類型中。那麼,你可以有fn get_tokens(&self) -> Vec<&str>;切片的壽命可以與包含data的對象的壽命相關聯。

+0

爲什麼轉換爲字符串會增加它們的壽命?他們是否屬於集裝箱? – ragingSloth 2014-11-21 22:27:44

+0

非常。 'Vec'和'String'是擁有容器。當你傳遞其中的一個時,實際上是轉移已分配內存的所有權來保存其值。 '&str'只是一個*借來的*參考;它只能活到它借來的東西。 – 2014-11-22 00:42:31