2016-11-11 19 views
2

我有一個包含值的結構,我想獲得該值進行動作的功能:如何返回具有對結構的引用的閉包?

struct Returner { 
    val: i32, 
} 

impl<'a> Returner { 
    fn get(&'a self) -> Box<Fn(i32) -> i32> { 
     return Box::new(|x| x + self.val); 
    } 
} 

這種失敗編譯:「類型[關閉...]不符合要求的一生」 。這是因爲閉包借用了self,這對我來說很好,因爲我不打算在struct被銷燬後使用獲得的函數。從我至今雲集,有兩種方法可以使人們有可能:

  1. 使用move關鍵字。我不想使用它,因爲它將獲取對象的所有權,並且希望在它返回此函數後使用它。

  2. 顯式指定閉包的生命週期以告訴編譯器它具有與從其調用的結構相同的生命週期。

我認爲2是一種正確的方式在我的情況,但我一直無法找到如何指定閉包的生命週期。有沒有直接的方式來做到這一點,或者我有這一切錯誤,它與Rust生存邏輯相矛盾?

回答

5

一般情況下,你可以通過編寫Box<Trait + 'a>指定盒裝特質對象的生命週期和類似的特質其他類型的指針後面的對象(如果它被省略,則默認爲'static至少在Box的情況下)。因此,在這種特定情況下,您需要返回類型Box<(Fn(i32) -> i32) + 'a>

但是,當你這樣做時,你會看到另一個關於self不夠長的錯誤。原因是(沒有move)關閉將捕獲參考本地變量self。解決方案是使用move。這不會移動Returner對象,它會將self這是參考移動到Returner對象。

因此,簡言之:

struct Returner { 
    val: i32, 
} 

impl<'a> Returner { 
    fn get(&'a self) -> Box<(Fn(i32) -> i32) + 'a> { 
     return Box::new(move |x| x + self.val); 
    } 
} 
+1

是我還是這''<'a>應佩戴'GET'而不是'impl'? –

+1

@MatthieuM。你是對的,應該的。它恰好在這裏沒有什麼區別,因爲''a'不會在其他地方出現,但對於量詞來說確實是錯誤的地方。 – delnan

+0

@ Matthieu M.我已經檢查了兩種方式,結果是一樣的。 – Month