2016-04-09 45 views
2

我有以下struct爲什麼這個struct成員需要兩個生命期?

struct PeekableRead<'a, R: Read> { 
    reader: &'a mut R, 
    peeked_octet: Option<u8>, 
} 

哪個rustc不喜歡:

…:27:1: 30:2 error: the parameter type `R` may not live long enough [E0309] 
…:27 struct PeekableRead<'a, R: Read> { 
…:28 reader: &'a mut R, 
…:29 peeked_octet: Option<u8>, 
…:30 } 
…:27:1: 30:2 help: run `rustc --explain E0309` to see a detailed explanation 
…:27:1: 30:2 help: consider adding an explicit lifetime bound `R: 'a`... 
…:27:1: 30:2 note: ...so that the reference type `&'a mut R` does not outlive the data it points at 
…:27 struct PeekableRead<'a, R: Read> { 
…:28 reader: &'a mut R, 
…:29 peeked_octet: Option<u8>, 
…:30 } 

如果我的壽命增加R,如,R: Read + 'a,它的工作原理。但是爲什麼?參考文獻'a是否指定了生命期?一定不要reader: &'a mut R,在struct PeekableRead<'a>住只要結構本身,因而「足夠長」?

奇怪的是,我似乎需要;如果我將'a添加到R並將其從參考中刪除,我仍然會得到error: missing lifetime specifier。我獲得成功編譯的唯一方法是兩種,但對我來說,它們似乎冗餘地指定了相同的東西。

(另外,爲什麼rustc輸出struct兩次輸出?第二個看起來像什麼就做一個建議,但似乎是完全一樣的我有什麼...)

回答

2

Doesn't the 'a on the reference specify the lifetime?

它規定了參考的的生存期,但不指定值的生命週期。這也解釋了你的意見,即

if I add 'a to R and remove it from the reference, I still get error: missing lifetime specifier.

對於結構是有效的,我們既需要:價值被指出仍必須活着,所以必須參考。 (雖然在邏輯上,第一個條件暗示了第二個條件,因爲參考永遠不會超過它指向的值)。

+1

您可以考慮struct PeekableRead 「結構的外部可見API,而這些字段是實現細節。然而,這種動機不是一個通用規則,因爲我們可以考慮結構的某些屬性,這些屬性沒有像這樣明確拼寫出來(每個泛型參數和自動特徵的方差)。 – bluss

0

引用上的生命週期參數指定了引用對象的壽命(即引用指向的對象)。該對象可能是一個引用,也可能是一個包含一個或多個引用的複雜對象。然而,當你使用一個特質時,這些參考背後的對象的生命期是隱藏的(特質本身並不知道這些生命期);生命週期是編譯器能夠正確理解這些生命週期的原因。

當您在引用後面使用泛型類型時,需要添加一個邊界以確保該類型的實例不包含比對那些實例的引用更短的引用。界限不是基於你如何使用類型而隱式添加的:界限不應該根據結構中的字段和你定義的類型的細節來改變。

例如,類型&'f File(對於每個'f)實施Read。我們可以使用該類型實例化PeekableRead:這給了我們一個PeekableRead<&'f File>PeekableRead<&'f File>存儲對&'f File的可變引用,因此reader字段的具體類型爲&'a mut &'f File。爲使此參考有效,'a必須短於或等於'f。如果'f短於'a,那麼您可以將&'f File替換爲在引用被刪除之前將被丟棄的那個,從而導致懸掛指針。當您添加綁定到R'a(即,當你寫R: Read + 'a),你說「實例R必須超過'a」(即R可能不包含短於'a的引用)。

相關問題