2017-01-14 8 views
1

Ich habe über Lebenszeiten gelesen und verstanden, dass jede einzelne Variable Bindung eine Lebensdauer hat. Es scheint jedoch so, als ob ich nicht an eine Zeit denken kann, die Sie wirklich brauchen würden, wenn man bedenkt, dass der Compiler eine sehr gute Arbeit leistet, wenn es notwendig ist.Wann ist es erforderlich, Lebensdauern zu verwenden?

Das Rust-Buch, habe ich gelesen. Ich hätte gerne ein Beispiel, das auch für jemanden wie mich einfach zu verstehen ist!

+1

Mögliche Duplikate von [Warum sind in Rust explizite Lebensdauern erforderlich?] (Http://stackoverflow.com/questions/31609137/why-are-explicit-lifetimes-needed-in-rust) – ljedrz

+0

ja, [diese Antwort] (http://StackOverflow.com/a/31609892/119861) in der Post Ijedrz Links hat ein Beispiel für einen Code, der explizite Lebenszeiten benötigt – hansaplast

+0

Obwohl ich stimme völlig darin überein, dass die Frage, die Sie mir verbunden haben, ähnlich der von mir ist, die Antwort @Francis Gagné hat mir wirklich eine gute Antwort gegeben, die es meiner Meinung nach besser erklärt als die Antworten auf die Frage, die du mir gestellt hast. Ich schätze Ihre Bemühungen. –

Antwort

2

Wir verwenden Lebensdauer Parameter in Rust, wenn eine Variable (das hat eine gewisse Lebensdauer) mit einer unterschiedlichen Lebensdauer auf eine andere Variable bezieht.

die diese beiden Aussagen lassen berücksichtigen:

let i = 42; 
let ref_i = &i; 

Hier i einige Lebenszeit hat, und ref_i hat eine andere Lebenszeit. Der Typ von ref_i kodiert jedoch die Lebensdauer von i (oder eine gewisse Annäherung davon, die Ton ist); Der Typ eines ausgeliehenen Zeigers wird geschrieben &'a T, und 'a ist die Lebensdauer des Referenten des Zeigers.

Ausgeborgte Zeiger können sich nur auf einen Wert beziehen, der eine längere Lebensdauer als die Lebensdauer des Zeigers hat. Wenn dies nicht der Fall wäre, würde der Zeiger schließlich dangling sein, d.h. er würde sich auf einen Wert beziehen, der nicht mehr existiert. Der Compiler überprüft dies automatisch für Sie (solange Sie keinen unsafe Code schreiben); das ist etwas, was andere Programmiersprachen wie C++ nicht tun. Aber um dies zu validieren, muss der Compiler die Lebensdauer des Werts kennen, auf den der Zeiger verweist; Deshalb haben wir in Rust lebenslange Parameter. Glücklicherweise kann der Compiler in vielen Situationen auch Lebensdauern ableiten, so dass er in diesen Situationen transparent ist.

Von Entwurf wird Rust nur lokale Inferenz machen. Beim Kompilieren einer Funktion untersucht der Compiler den Rumpf anderer Funktionen oder anderer Typen nicht, um zu überprüfen, ob die erste Funktion korrekt ist. es schaut nur auf ihre Unterschrift. Für Funktionen haben wir Elisionsregeln, die vorschreiben, wann explizite Lebensdauerparameter wegfallen und was der Compiler daraus ableiten wird. Für Strukturen müssen wir sie immer explizit erwähnen, weil wir fast immer den Lebensdauerparameter der Struktur mit einem anderen Element korrelieren müssen (z. B. den Lebensdauerparameter eines Merkmals in einem Merkmalsimpl oder den Rückgabetyp einer Methode). und da der Compiler nur eine lokale Typ-Inferenz durchführt, müssen wir diese Korrelation explizit in der Signatur kodieren.

Hier ist ein einfaches Beispiel für eine Struktur, die eine borrow enthält:

struct Wrapper<'a>(&'a str); 

impl<'a> Wrapper<'a> { 
    fn extract(self) -> &'a str { 
     self.0 
    } 
} 

Zuerst auf der Struktur Definition benötigen wir eine Lebensdauer Parameter für die String-Scheibe einzuführen. Dann müssen wir die impl weil Wrapper erwartet eine Lebensdauer Parameter ('a in impl<'a>definiert die Lebensdauer Parameter, die 'a in Wrapper<'a>verwendet die Lebensdauer Parameter) parametrieren. Unter extract können wir uns auf den 'a Lebensdauerparameter beziehen, der auf impl definiert ist, so dass der Rückgabetyp der Funktion dem tatsächlichen Typ von self.0 entspricht.

Verwandte Themen