Leçons du module (1/2)
Lifetimes et références
En Rust, chaque référence a une durée de vie (lifetime), qui correspond à la portée (scope) à l'intérieur de laquelle cette référence est valide. La plupart du temps, les durées de vie sont implicites et déduites par le compilateur grâce aux règles d'élision. Cependant, lorsque la relation entre les durées de vie de différentes références est ambiguë, nous devons les annoter explicitement.
L'objectif principal des durées de vie est de prévenir les références pendantes (dangling references : références à des données qui ont déjà été libérées de la mémoire).
La Syntaxe des Annotations de Durée de Vie
Les noms de durées de vie commencent par une apostrophe (') et sont généralement écrits sous forme de lettres minuscules très courtes (comme 'a). Les annotations de durée de vie ne modifient pas la durée réelle des variables, mais indiquent au compilateur la relation de validité entre les références reçues et celles éventuellement renvoyées.
Par exemple, si une fonction prend deux paramètres qui sont des références à des chaînes de caractères et renvoie une référence à une chaîne, et que nous voulons que la référence renvoyée reste valide tant que les deux paramètres d'entrée sont valides, nous utilisons :
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
Durée de vie dans les Structures de données
Si une structure de données contient un champ qui est une référence, nous devons annoter explicitement la durée de vie de cette référence pour garantir que l'instance de la struct ne puisse pas survivre aux données auxquelles elle fait référence :
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,
};
}
La Durée de Vie Statique
La durée de vie 'static est une durée de vie spéciale qui s'étend sur toute la durée de l'exécution du programme. Tous les littéraux de chaînes (&str) ont implicitement une durée de vie 'static car ils sont encodés directement à l'intérieur de l'exécutable binaire.
let s: &'static str = "Ho un lifetime statico.";
À toi de jouer
Exercice 1 : La fonction longest
Écrivez une fonction nommée longest<'a> qui accepte deux paramètres, x de type &'a str et y de type &'a str, et renvoie une valeur de type &'a str. À l'intérieur de la fonction, utilisez une structure if/else pour renvoyer le paramètre x si sa longueur est supérieure à celle de y, sinon renvoyez y.
Afficher l'indice
Déclarez la signature avec `fn longest<'a>(x: &'a str, y: &'a str) -> &'a str`. Utilisez ensuite `if x.len() > y.len() { x } else { y }`.
Solution disponible après 3 tentatives
Exercice 2 : Structures avec références
Définissez une structure nommée Excerpt<'a> contenant un seul champ nommé part de type &'a str. Dans le main, créez une variable chaîne nommée text et instanciez une variable excerpt de type Excerpt en lui passant une référence à text. Affichez excerpt.part à l'écran.
Afficher l'indice
Utilisez `struct Excerpt<'a> { part: &'a str }`. Dans le main, instanciez-la avec `Excerpt { part: &text }`.
Solution disponible après 3 tentatives
Exercice 3 : Références statiques
Déclarez une variable nommée message avec une annotation de type explicite pour la durée de vie statique (&'static str), en lui assignant une chaîne littérale. Affichez la valeur de message à l'écran.
Afficher l'indice
Utilisez la syntaxe `let message: &'static str = 'Messaggio statico!';` pour annoter explicitement la durée de vie statique.
Solution disponible après 3 tentatives