Przejdź do głównej treści
eLearner.app
Moduł 6 · Lekcja 1 z 211/14 w kursie~15 min
Lekcje modułu (1/2)

Lifetimes i referencje

W języku Rust każda referencja posiada okres ważności (lifetime), który odpowiada zakresowi (scope), w którym ta referencja jest prawidłowa. Przez większość czasu okresy ważności są implikowane i dedukowane przez kompilator dzięki regułom elizji. Jednak kiedy relacja między okresami ważności różnych referencji jest niejednoznaczna, musimy je zapisać jawnie.

Głównym celem stosowania okresów ważności (lifetimes) jest zapobieganie powstawaniu wiszących referencji (dangling references) (referencji do danych, które zostały już usunięte z pamięci).


Składnia adnotacji okresów ważności (Lifetimes)

Nazwy okresów ważności zaczynają się od apostrofu (') i są zazwyczaj zapisywane za pomocą bardzo krótkich, małych liter (jak 'a). Adnotacje okresów ważności nie zmieniają rzeczywistego czasu życia zmiennych, lecz wskazują kompilatorowi relację ważności pomiędzy referencjami przekazanymi jako argumenty a tymi ewentualnie zwracanymi.

Na przykład, jeśli funkcja przyjmuje dwa parametry będące referencjami do tekstu i zwraca referencję do tekstu, a chcemy, aby zwracana referencja była ważna tak długo, jak oba parametry wejściowe, piszemy:

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

Okresy ważności (Lifetimes) w strukturach danych

Jeśli struktura danych zawiera pole będące referencją, musimy jawnie określić okres ważności tej referencji, aby zagwarantować, że instancja struktury nie przeżyje danych, do których się odnosi:

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

Statyczny okres ważności (Lifetime Statico)

Okres ważności 'static to specjalny czas życia, który trwa przez cały okres wykonywania programu. Wszystkie literały tekstowe (&str) posiadają implikowany czas życia 'static, ponieważ są zakodowane bezpośrednio w pliku wykonywalnym (binarnym).

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

Spróbuj sam

Esercizio 1: Funkcja longest

Ćwiczenie#rust.m6.l1.e1
Próby: 0Ładowanie...

Napisz funkcję o nazwie longest<'a>, która przyjmuje dwa parametry: x typu &'a str oraz y typu &'a str, i zwraca wartość typu &'a str. Wewnątrz funkcji użyj konstrukcji if/else do zwrócenia parametru x, jeśli jego długość jest większa niż y, a w przeciwnym razie zwróć y.

Ładowanie edytora...
Pokaż wskazówkę

Zadeklaruj sygnaturę za pomocą `fn longest<'a>(x: &'a str, y: &'a str) -> &'a str`. Następnie użyj `if x.len() > y.len() { x } else { y }`.

Rozwiązanie dostępne po 3 próbach

Esercizio 2: Struktury z referencjami

Ćwiczenie#rust.m6.l1.e2
Próby: 0Ładowanie...

Zdefiniuj strukturę o nazwie Excerpt<'a> zawierającą jedno pole o nazwie part typu &'a str. W funkcji main utwórz zmienną tekstową o nazwie text i utwórz instancję zmiennej excerpt typu Excerpt przekazując referencję do text. Wypisz w konsoli excerpt.part.

Ładowanie edytora...
Pokaż wskazówkę

Użyj `struct Excerpt<'a> { part: &'a str }`. W main utwórz jej instancję za pomocą `Excerpt { part: &text }`.

Rozwiązanie dostępne po 3 próbach

Esercizio 3: Referencje statyczne

Ćwiczenie#rust.m6.l1.e3
Próby: 0Ładowanie...

Zadeklaruj zmienną o nazwie message z jawną adnotacją typu dla statycznego czasu życia (&'static str), przypisując jej wartość literału tekstowego. Wypisz wartość message na ekranie.

Ładowanie edytora...
Pokaż wskazówkę

Użyj składni `let message: &'static str = 'Messaggio statico!';` do jawnego określenia statycznego czasu życia.

Rozwiązanie dostępne po 3 próbach