Strukturen in Rust können Verweise auf andere Objekte durch die Angabe von expliziten Lebensdauern (lifetimes) in der Strukturdefinition speichern. Dies ist erforderlich, damit der Compiler überprüfen kann, dass kein Verweis ungültig wird. Hier ist ein Beispiel:
struct Book<'a> { title: &'a str, author: &'a str, }
Hier enthält die Struktur Book zwei Verweise mit der gleichen Lebensdauer 'a. Wenn Sie eine Funktion schreiben, die eine solche Struktur zurückgibt, müssen Sie garantieren, dass alle Verweise in ihr außerhalb der internen Logik der Funktion gültig sind:
fn book_factory<'a>(title: &'a str, author: &'a str) -> Book<'a> { Book { title, author } }
Wenn Sie versuchen, aus einer Funktion eine Struktur zurückzugeben, bei der die Verweisfelder beispielsweise auf lokale Variablen dieser Funktion zeigen, tritt ein Kompilierungsfehler auf, da die Lebensdauer der Verweise nicht ausreicht, um einen sicheren Zugriff zu gewährleisten.
Kann man eine Struktur erstellen, die in einem der Felder einen Verweis (&str) und in einem anderen ein String enthält? Warum könnte das ein Problem sein?
Häufig irrtümlich antworten: "Ja, das ist möglich, das ist sicher".
Tatsächlich, wenn &str aus einem String erhalten wird und die Struktur diesen String überlebt, wird der Verweis zu einem hängenden Verweis (dangling reference). Zum Beispiel:
struct Test<'a> { s1: &'a str, s2: String, } fn main() { let s = String::from("hello"); let t = Test { s1: &s, s2: s }; // t.s1 ist tatsächlich nur sicher, solange s2 (s) lebt, aber wenn s2 zuerst gelöscht wird — Fehler }
Geschichte In einem Projekt wurde versucht, aus einer ladenden Funktion eine Struktur zurückzugeben, die einen Verweis auf eine temporäre Zeichenkette enthielt, die innerhalb derselben Funktion erstellt wurde. Der Code konnte nicht kompiliert werden, es war ein erheblicher Umstrukturierungsbedarf erforderlich, um die Lebensdauer der lokalen Variable zu entfernen.
Geschichte Ein Entwickler beabsichtigte, eine Struktur mit einem Verweis auf ein Array-Element zu verwenden, das in der Funktion erstellt wurde, aber nach der Rückgabe stellte sich heraus, dass dieser Verweis ungültig war, was der Compiler erfolgreich verhinderte.
Geschichte In einem Unternehmensprojekt speicherten Entwickler einen Verweis &str auf eine Zeichenkette aus einem anderen Objekt, das aus der Sammlung entfernt wurde, bevor der Verweis selbst — beim nächsten Zugriff auf diesen Verweis trat ein panic auf.