2015-02-23 76 views
5

我試圖教我一些鐵鏽,並已書面的東西,看起來像:如何將返回值的生命週期設置爲我移入其中的變量的生命週期?

let args:Vec<String> = env::args().collect(); 
let parsed = parser::sys(args.as_slice()); 

...

pub fn sys<'a>(args:&'a [String]) -> Parsed<'a> { 
    parsed(args) 
} 

其中parsed是一個分析和負荷CONFIGS功能。

這工作正常。現在,我試圖抽象掉顯式調用env::args(),並隱藏在調用sys,所以我寫的sys

pub fn sys<'a>() -> Parsed<'a> { 
    let args:Vec<String> = env::args().collect(); 
    parsed(args.as_slice()) 
} 

一個新的版本而與此失敗:

error: `args` does not live long enough 
src/test.rs:66  parsed(args.as_slice()) 

我認爲錯誤是因爲編譯器無法推斷出我希望這個新創建的結構的生命週期是我想要將其移入的變量的生命週期。它是否正確?我將如何註解這個返回值的生命週期/修復此問題?

回答

3

我認爲這個錯誤是因爲沒有辦法讓編譯器推斷我希望這個新創建的結構體的生命週期是我想要將它移入的變量的生命週期。

其實沒有。

的錯誤是因爲你試圖創建引用到變量args這將不再是有效的,你從sys因爲args返回後,一個局部變量,因此在sys末被丟棄。

如果您想使用引用,你可以提供sys&'a mut Vec<String>(空),填充在sys,並返回對它的引用:

pub fn sys<'a>(args: &'a mut Vec<String>) -> Parsed<'a> { 
    *args = env::args().collect(); 
    parsed(args.as_slice()) 
} 

這保證了args活得比的sys電話。這將在結果的整個生命週期內借用args

另一種解決方案是取消'a,只是簡單地讓Parsed擁有它的元素而不是引用它們;然而沒有Parsed的定義,我不能建議如何最好地這樣做。

+0

是否沒有辦法將參數「移出」sys,例如:像std:移動或複製elision。下面的工作,但我也分配給本地變量,但不知何故,我認爲編譯器知道如何將其移出: pub fn contents(source:&String) - > Vec { let mut reader = BufferedReader: :new(File :: open(&Path :: new(source))); reader.lines()。map(| l | l.unwrap())collect() } – sgldiv 2015-02-23 11:26:51

+0

@sgldiv'Reader :: lines'是一個'Iterator ',而不是'Iterator '。您返回一個'Vec ',它擁有所有返回的數據的完全所有權。沒有什麼東西可以借用返回值,編譯器神奇地默默地移動。 – delnan 2015-02-23 11:43:06

+0

這是有道理的。謝謝! – sgldiv 2015-02-23 11:58:16