Direkt zum Hauptinhalt springen
eLearner.app
Modul 6 · Lektion 1 von 211/14 im Kurs~15 min
Lektionen des Moduls (1/2)

Lifetimes und Referenzen

In Rust hat jede Referenz eine Lebensdauer (Lifetime). Dies entspricht dem Gültigkeitsbereich (Scope), innerhalb dessen diese Referenz gültig ist. Meistens sind Lebensdauern implizit und werden vom Compiler dank der Elisionsregeln abgeleitet. Wenn jedoch die Beziehung zwischen den Lebensdauern verschiedener Referenzen mehrdeutig ist, müssen wir sie explizit deklarieren.

Das Hauptziel von Lebensdauern besteht darin, hängende Referenzen (Dangling References) zu verhindern (Referenzen auf Daten, die bereits aus dem Speicher freigegeben wurden).


Die Syntax von Lebensdauer-Annotationen

Die Namen von Lebensdauern beginnen mit einem Apostroph (') und werden normalerweise in sehr kurzen Kleinbuchstaben geschrieben (wie 'a). Lebensdauer-Annotationen ändern nicht die tatsächliche Lebensdauer von Variablen, sondern zeigen dem Compiler die Gültigkeitsbeziehung zwischen den empfangenen und eventuell zurückgegebenen Referenzen an.

Wenn beispielsweise eine Funktion zwei Parameter erhält, die Referenzen auf einen String sind, und eine Referenz auf einen String zurückgibt, und wir möchten, dass die zurückgegebene Referenz gültig ist, solange beide Eingabeparameter gültig sind, verwenden wir:

Code
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

Lebensdauer in Datenstrukturen

Wenn eine Datenstruktur ein Feld enthält, das eine Referenz ist, müssen wir die Lebensdauer auf dieser Referenz explizit annotieren. Dadurch wird garantiert, dass die Instanz der Struct die Daten, auf die sie verweist, nicht überleben kann:

Code
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Chiamami Ismaele. Alcuni anni fa...");
    let first_sentence = novel.split('.').next().unwrap();
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}

Die statische Lebensdauer

Die Lebensdauer 'static ist eine spezielle Lebensdauer, die die gesamte Ausführungsdauer des Programms überdauert. Alle String-Literale (&str) haben implizit eine 'static-Lebensdauer, da sie direkt in die Binärdatei kodiert sind.

Code
let s: &'static str = "Ho un lifetime statico.";

Probiere es aus

Übung 1: Die longest-Funktion

Übung#rust.m6.l1.e1
Versuche: 0Wird geladen…

Schreiben Sie eine Funktion namens longest<'a>, die zwei Parameter akzeptiert, x vom Typ &'a str und y vom Typ &'a str, und einen Wert vom Typ &'a str zurückgibt. Verwenden Sie innerhalb der Funktion ein if/else-Konstrukt, um den Parameter x zurückzugeben, wenn seine Länge größer als die von y ist, andernfalls y.

Editor wird geladen…
Hinweis anzeigen

Deklarieren Sie die Signatur mit `fn longest<'a>(x: &'a str, y: &'a str) -> &'a str`. Verwenden Sie dann `if x.len() > y.len() { x } else { y }`.

Lösung nach 3 Versuchen verfügbar

Übung 2: Strukturen mit Referenzen

Übung#rust.m6.l1.e2
Versuche: 0Wird geladen…

Definieren Sie eine Struktur namens Excerpt<'a>, die ein einzelnes Feld namens part vom Typ &'a str enthält. Erstellen Sie in der main-Methode eine String-Variable namens text und instanziieren Sie eine Variable excerpt vom Typ Excerpt, indem Sie eine Referenz auf text übergeben. Geben Sie excerpt.part auf dem Bildschirm aus.

Editor wird geladen…
Hinweis anzeigen

Verwenden Sie `struct Excerpt<'a> { part: &'a str }`. Instanziieren Sie sie in main mit `Excerpt { part: &text }`.

Lösung nach 3 Versuchen verfügbar

Übung 3: Statische Referenzen

Übung#rust.m6.l1.e3
Versuche: 0Wird geladen…

Deklarieren Sie eine Variable namens message mit expliziter Typannotation für die statische Lebensdauer (&'static str) und weisen Sie ihr ein String-Literal zu. Geben Sie den Wert von message aus.

Editor wird geladen…
Hinweis anzeigen

Verwenden Sie die Syntax `let message: &'static str = 'Messaggio statico!';`, um die statische Lebensdauer explizit zu annotieren.

Lösung nach 3 Versuchen verfügbar