Modulelessen (1/2)
Levensduren en referenties
In Rust heeft elke referentie een levensduur, wat overeenkomt met de reikwijdte waarbinnen die referentie geldig is. Meestal zijn levensduren impliciet en afgeleid door de compiler dankzij regels voor levenslange elisie. Wanneer de relatie tussen de levensduur van verschillende referenties echter dubbelzinnig is, moeten we deze expliciet annoteren.
Het belangrijkste doel van levens is het voorkomen van bungelende referenties (verwijzingen naar gegevens waarvan de toewijzing al uit het geheugen is ongedaan gemaakt).
Syntaxis van levenslange annotaties
Levenslange namen beginnen met een apostrof (') en zijn meestal korte kleine letters (zoals 'a). Levensduurannotaties veranderen de werkelijke levensduur van variabelen niet, maar geven aan de compiler de relatie aan tussen de geldigheid van invoer en uitvoer.
Als een functie bijvoorbeeld twee tekenreeksreferentieparameters gebruikt en een tekenreeksreferentie retourneert, en we willen dat de geretourneerde referentie geldig is zolang beide invoerparameters geldig zijn, gebruiken we:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}Levens in datastructuren
Als een structuur een veld bevat dat een referentie is, moeten we expliciet de levensduur van die referentie annoteren om ervoor te zorgen dat de struct-instantie de gegevens waarnaar deze verwijst niet kan overleven:
struct ImportantExcerpt<'a> {
part: &'a str,
}
fn main() {
let novel = String::from("Call me Ishmael. Some years ago...");
let first_sentence = novel.split('.').next().unwrap();
let i = ImportantExcerpt {
part: first_sentence,
};
}Het statische leven
De 'static levensduur is een speciale levensduur die de gehele duur van het programma duurt. Alle letterlijke tekenreeksen (&str) hebben impliciet een levensduur van 'static omdat ze rechtstreeks in het binaire uitvoerbare bestand worden opgeslagen.
let s: &'static str = "I have a static lifetime.";Probeer het zelf
Oefening 1: De langste functie
Schrijf een functie met de naam langste<'a> die twee parameters accepteert, x van het type &'a str en y van het type &'a str, en een waarde retourneert van het type &'a str. Gebruik binnen de functie een if/else-blok om x terug te geven als de lengte ervan groter is dan y, en anders y.
Toon hint
Declareer de handtekening met `fn langste<'a>(x: &'a str, y: &'a str) -> &'a str`. Gebruik dan `if x.len() > y.len() { x } else { y }`.
Oplossing beschikbaar na 3 pogingen
Oefening 2: Structuren met referenties
Definieer een structuur met de naam Excerpt<'a> die een enkel veld bevat met de naam onderdeel van het type &'a str. Maak in de hoofdfunctie een tekenreeksvariabele met de naam tekst en instantiëer een variabel uittreksel van het type Excerpt door een verwijzing naar tekst te lenen. Print uittreksel.deel.
Toon hint
Gebruik `struct Excerpt<'a> { part: &'a str }`. In de hoofdsituatie maak je het met `Excerpt { part: &text }`.
Oplossing beschikbaar na 3 pogingen
Oefening 3: Statische referenties
Declareer een variabele met de naam message met een expliciete typeannotatie voor de statische levensduur (&'static str), en wijs er een letterlijke tekenreeks aan toe. Druk de waarde van het bericht af.
Toon hint
Gebruik de syntaxis `let message: &'static str = 'Messaggio statico!';` om expliciet de statische levensduur te annoteren.
Oplossing beschikbaar na 3 pogingen