ProgrammationDéveloppeur Rust

Comment fonctionne la gestion des collections en Rust (par exemple, Vec, HashMap) ? Quelles sont les spécificités de leur propriété et quand est-il nécessaire de cloner les éléments ou la collection ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Rust, les collections standard (comme Vec<T>, HashMap<K,V>, HashSet<T>, etc.) implémentent le principe de propriété du contenu. Cela signifie que la collection possède tous les objets qu'elle contient et est responsable de la libération de leur mémoire lors de la suppression.

Par exemple, les éléments placés dans Vec<T> sont déplacés (move) dans le vecteur, qui les possède ensuite :

let s = String::from("hi"); let mut v = Vec::new(); v.push(s); // s est maintenant déplacé, non accessible

Si la collection contient des valeurs copiables, elles sont copiées ; si elles sont déplacées, les droits de propriété sont transférés. Il est nécessaire de cloner des éléments ou une collection lorsqu'il faut conserver la valeur initiale à deux endroits, par exemple :

let name = String::from("Olga"); let mut v = Vec::new(); v.push(name.clone()); println!("{}", name); // name est toujours accessible, car il a été cloné

Question piège

Que se passe-t-il lors de l'insertion d'un élément dans un HashMap si l'on utilise un type de données déplacé (par exemple, String) comme clé ? La clé d'origine sera-t-elle accessible après son passage dans HashMap::insert() ?

On donne souvent une réponse incorrecte : "La clé d'origine restera accessible après l'insertion".

En réalité, la propriété de la clé et de la valeur est transférée au HashMap, et après l'insertion, elles ne peuvent pas être utilisées sans un clonage préalable :

let key = String::from("id"); let mut map = std::collections::HashMap::new(); map.insert(key, 42); // key n'est plus accessible

Tenter d'accéder à key provoquera une erreur de compilation.

Exemples d'erreurs réelles dues à une mauvaise compréhension des subtilités du sujet


Histoire Un développeur a essayé d'utiliser un objet déplacé après son insertion dans Vec et a reçu l'erreur "value used here after move", ne comprenant pas que le Vector en possède maintenant.


Histoire Lors de l'utilisation de HashMap, nous avons oublié de cloner les clés de chaîne, ce qui a conduit à l'incapacité de les utiliser ailleurs, entraînant des refactorisations majeures du code.


Histoire Dans l'un des projets, nous avons tenté de retourner une référence à un élément interne du vecteur en dehors de la fonction, oubliant que la référence serait invalidée lors du changement de taille du vecteur. Cela a conduit à des références pendantes et à un crash à l'exécution (panic).