ProgrammationDéveloppeur systèmes Rust

Une structure en Rust peut-elle contenir des références à d'autres objets ? Quelles sont les restrictions concernant la durée de vie de ces références et que se passe-t-il si l'on tente de retourner d'une fonction une structure avec des références à durée de vie incomplète ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Les structures en Rust peuvent stocker des références à d'autres objets en spécifiant des durées de vie explicites (lifetimes) dans la définition de la structure. Cela est nécessaire pour que le compilateur puisse vérifier qu'aucune référence ne deviendra invalide. Voici un exemple :

struct Book<'a> { title: &'a str, author: &'a str, }

Ici, la structure Book contient deux références avec la même durée de vie 'a. Lorsque vous écrivez une fonction qui retourne une telle structure, vous devez garantir que toutes les références qu'elle contient seront valides indépendamment de la logique interne de la fonction :

fn book_factory<'a>(title: &'a str, author: &'a str) -> Book<'a> { Book { title, author } }

Si vous essayez de retourner d'une fonction une structure où les champs de référence pointent, par exemple, vers des variables locales de cette fonction, une erreur de compilation se produira, car la durée de vie des références n'est pas suffisante pour un accès sécurisé.

Question piège

Peut-on créer une structure qui contient une référence (&str) dans un champ et un String dans un autre ? Pourquoi cela peut-il poser problème ?

La réponse souvent erronée : "Oui, c'est possible, c'est sûr".

En réalité, si &str est obtenu à partir d'un String et que la structure survit à ce String, la référence deviendra une référence pendante (dangling reference). Par exemple :

struct Test<'a> { s1: &'a str, s2: String, } fn main() { let s = String::from("hello"); let t = Test { s1: &s, s2: s }; // t.s1 est en fait sûr uniquement tant que s2 (s) est vivant, mais si s2 est supprimé en premier — erreur }

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


Histoire Dans un projet, on a essayé de retourner d'une fonction de chargement une structure contenant une référence à une chaîne temporaire créée à l'intérieur de cette même fonction. Le code n'a pas pu être compilé, nécessitant une réécriture significative pour supprimer la durée de vie de la variable locale.


Histoire Un développeur avait l'intention d'utiliser une structure avec une référence à un élément d'un tableau créé dans une fonction, mais après le retour, cette référence s'est révélée invalide, ce que le compilateur a réussi à prévenir.


Histoire Dans un projet d'entreprise, les développeurs ont stocké une référence &str à une chaîne d'un autre objet qui avait été supprimé de la collection avant que la référence elle-même — lors d'un accès ultérieur à cette référence, un panic s'est produit.