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