2016-07-28 44 views
3

爲什麼Rust編譯器發出一個錯誤,要求我限制下列結構中泛型參數的生存期?Rust編譯器爲什麼要求我限制泛型類型參數的生存期(錯誤E0309)?

pub struct NewType<'a, T> { 
    x: &'a T, 
} 
error[E0309]: the parameter type `T` may not live long enough 
--> src/main.rs:2:5 
    | 
2 |  x: &'a T, 
    |  ^^^^^^^^ 
    | 
    = help: consider adding an explicit lifetime bound `T: 'a`... 
note: ...so that the reference type `&'a T` does not outlive the data it points at 
--> src/main.rs:2:5 
    | 
2 |  x: &'a T, 
    |  ^^^^^^^^ 

我可以通過改變

pub struct NewType<'a, T> 
where 
    T: 'a, 
{ 
    x: &'a T, 
} 

我不明白爲什麼它是必要的T: 'a部件添加到結構定義修復它。我想不到T中包含的數據可能會超過對T的引用。 x的引用需要超過NewType結構,如果T是另一個結構,那麼它需要符合它包含的任何引用的相同條件。

是否有一個具體的例子,這種類型的註釋是必要的,或者是鏽編譯器只是迂腐?

+0

這會讓你更加困惑於相關的類型。你必須綁定 :: Associated:'a *即使你已經綁定了T的一生,這對我來說並沒有什麼意義。 – LinearZoetrope

回答

5

什麼T: 'a的意思是,在T任何引用必須活得比'a

這意味着,你不能這樣做:

let mut o: Option<&str> = Some("foo"); 
let mut nt = NewType { x: &o }; // o has a reference to &'static str, ok. 

{ 
    let s = "bar".to_string(); 
    let o2: Option<&str> = Some(&s); 
    nt.x = &o2; 
} 

這將是危險的,因爲nt將有塊後懸掛參考s。在這種情況下,它會抱怨o2沒有足夠長的時間。

我不能想辦法,你可以有一個&'a參考的東西包含短壽命參考,並明確了編譯器知道以某種方式這個(因爲它告訴你添加的約束)。不過,我認爲在某些方面闡明限制是有幫助的,因爲它使得借用檢查器不那麼神奇:只需從類型聲明和函數簽名就可以推斷它,而無需查看字段如何定義(通常是實現這些細節不在文檔中)或者如何實現一個函數。

+0

我同意明確表示絕不是壞事。我經常會問「源碼是否超出了目的地」的問題,並且在這種情況下,編寫示例很難,因爲我知道編譯器會拒絕它。感謝這個簡單而清晰的例子。 – Novus

相關問題