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:
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:
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).
let s: &'static str = "Ho un lifetime statico.";
Spróbuj sam
Esercizio 1: Funkcja longest
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.
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
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.
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
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.
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