2016-07-28 21 views
3

Warum gibt der Rust-Compiler einen Fehler aus, der mich auffordert, die Lebensdauer des generischen Parameters in der folgenden Struktur einzuschränken?Warum fordert die Rust-Compiler-Anfrage die Lebensdauer eines generischen Typparameters auf (Fehler 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, 
    |  ^^^^^^^^ 

Ich kann es beheben, indem

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

an sich ändernde Ich verstehe nicht, warum es notwendig ist, die T: 'a Teil der Strukturdefinition hinzuzufügen. Ich kann mir nicht vorstellen, dass die in T enthaltenen Daten den Verweis auf T überleben könnten. Der Referent von x muss die NewType Struktur überleben und wenn T eine andere Struktur ist, dann müsste es die gleichen Kriterien für alle Referenzen erfüllen, die es auch enthält.

Gibt es ein spezifisches Beispiel, wo diese Art von Annotation notwendig wäre oder ist der Rust-Compiler nur pedantisch?

+0

Dies wird doppelt verwirrend mit den zugehörigen Typen.Sie müssen binden :: Associated: 'a *, auch wenn * Sie bereits T Lebenszeit gebunden, die für mich nicht wirklich sinnvoll ist. – LinearZoetrope

Antwort

5

Was T: 'a sagt ist, dass alle Referenzen in T'a überleben müssen.

Was dies bedeutet, ist, dass Sie nicht wie etwas tun:

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; 
} 

Dies wäre gefährlich, weil nt einen baumelnden Bezug auf s nach dem Block haben würde. In diesem Fall würde es auch beklagen, dass o2 auch nicht lange genug lebte.

Ich kann nicht denken Sie an eine Art und Weise Sie eine &'a Bezug auf etwas haben kann, die kürzere Lebensdauer Referenzen enthält, und eindeutig der Compiler weiß dies in irgendeiner Weise (weil es Ihnen sagt die Einschränkung hinzufügen). Ich denke jedoch, dass es in gewisser Weise hilfreich ist, die Einschränkung zu formulieren, da der Borrow-Checker dadurch weniger magisch wird: Man kann nur aufgrund von Typdeklarationen und Funktionssignaturen argumentieren, ohne sich die Definition der Felder ansehen zu müssen (oft Implementierung) Details, die nicht in der Dokumentation enthalten sind) oder wie die Implementierung einer Funktion.

+0

Ich stimme zu, dass es keine schlechte Sache ist, explizit zu sein. Ich stelle immer die Frage, ob die Quelle das Ziel überlebt, und mit dieser Gemütsverfassung ist es schwierig, ein Beispiel zu schreiben, weil ich wusste, dass der Compiler es implizit ablehnen würde. Danke für das einfache, aber klärende Beispiel. – Novus