RAII (Resource Acquisition Is Initialization) est un idiome venu du C++, où la durée de vie d'une ressource est strictement liée à la durée de vie d'un objet dans la pile. En Rust, ce concept est à la base du système de propriété et de libération des ressources, ce qui permet de se passer de ramasse-miettes classiques (GC).
De nombreux langages gèrent la mémoire et les ressources à l'aide d'un ramasse-miettes, qui nettoie périodiquement les objets inutiles. Cette stratégie augmente les latences et ne garantit pas la libération immédiate des ressources externes (fichiers, sockets, etc.). Dans la programmation bas niveau et système, une telle situation est inacceptable : une précision et une détermination dans la gestion des ressources sont nécessaires.
En Rust, chaque objet possède sa ressource et la libère strictement au moment de sa destruction (sortie de la portée), grâce à l'appel de Drop (similaire au destructeur). Par conséquent, les ressources sont libérées immédiatement, et toutes les erreurs de libération implicite sont réduites au minimum. Le système de types et de propriété de Rust prévient les fuites et la double libération presque au moment de la compilation.
Exemple de code :
struct FileWrapper { file: std::fs::File, } impl Drop for FileWrapper { fn drop(&mut self) { println!("FileWrapper ferme le fichier ! (sortie de portée)"); } } fn main() { let _fw = FileWrapper { file: std::fs::File::create("test.txt").unwrap() }; // À la sortie de main, drop est garanti d'être appelé }
Caractéristiques clés :
Drop est-il appelé pour des valeurs qui ont été déplacées (moved) auparavant ?
Non, après le déplacement d'une valeur, Drop n'est appelé que pour le nouveau propriétaire, l'ancien objet est considéré comme "vide" et Drop ne s'exécute pas.
let file1 = FileWrapper {...}; let file2 = file1; // file1 déplacé // Drop sera appelé une fois — pour file2
Une panique (panic!) ou unwrap() au milieu de la portée peut-elle empêcher l'appel de drop ?
Non, une panique ou une sortie par erreur n'annule pas l'appel du destructeur — Drop sera forcément appelé pour tous les objets sortis de la portée.
Si une référence possède un objet, Drop sera-t-il appelé à la fin de la durée de vie de la référence ?
Non, drop est appelé uniquement pour le propriétaire de l'objet, les références n'effectuent pas de possession. Un pointeur intelligent est nécessaire pour les ressources heap.
Le développeur a passé un descripteur de fichier par référence à une fonction d'écriture. À la fin de l'exécution du programme, le fichier a conservé un verrou, car drop n'a pas été appelé (il n'y avait pas de propriétaire, une référence était utilisée).
Avantages :
Inconvénients :
La propriété de la ressource a toujours été transférée par des structures réalisant Drop. Tous les fichiers, connexions ou verrous ouverts sont automatiquement libérés à la fin de la portée ou lors d'une panique. Une carte blanche pour une gestion sûre et triviale des ressources même dans des projets complexes.
Avantages :
Inconvénients :