Le trait Drop permet de définir une logique de nettoyage personnalisée pour une res source lorsqu'elle sort de sa portée. Il est généralement utilisé pour libérer des ressources telles que des fichiers, des réseaux, des ressources externes et non sécurisées. Drop est appelé automatiquement par le compilateur.
Exemple :
struct FileWrapper { fd: i32, } impl Drop for FileWrapper { fn drop(&mut self) { println!("Fermeture de fd: {}", self.fd); unsafe { libc::close(self.fd); } } } fn main() { let file = FileWrapper { fd: 42 }; } // drop est appelé automatiquement
Particularités :
file.drop(), mais on peut l'appeler via std::mem::drop(file).panic!) à l'intérieur d'un drop — cela entraînera un "double panic" et l'arrêt du processus.Question : Que se passe-t-il si, lors du drop() d'une structure, on tente de transmettre la possession de la ressource à une autre partie du programme — par exemple, la retourner depuis le drop ?
Réponse : On ne peut pas "sauver" ou transmettre la valeur d'un champ de structure pendant le drop à quiconque d'autre, à part dans le drop lui-même ; essayer de retourner ou de transmettre une valeur entraînera une erreur de compilation ou une violation de la sécurité de la mémoire (si on utilise unsafe). Exemple d'erreur :
impl Drop for MyStruct { fn drop(&mut self) -> T { // Erreur : Drop::drop ne peut pas retourner une valeur ! ... } }
Histoire
Dans un processeur de fichiers, on a oublié d'implémenter Drop pour une structure enveloppant directement un descripteur de fichier brut. Après des centaines d'opérations, on a rencontré la "limite de descripteurs de fichiers atteinte" — les ressources n'étaient pas nettoyées.
Histoire
Dans une bibliothèque réseau, on a implémenté Drop pour un wrapper autour d'une connexion TCP, mais lors du drop, une panique s'est produite à cause d'une erreur de fermeture de socket. Cela a mené à l'arrêt d'un thread lors d'un double panic (la seule solution — éviter la panique dans Drop !).
Histoire
Dans un système de plugins, on a essayé de réaliser un nettoyage avec Drop, en créant de nouvelles ressources pendant le drop (par exemple, journalisation dans un fichier). Cela a conduit à "déjà emprunté : BorrowMutError" à cause d'appels récursifs de drop pour des structures liées et à des fuites de ressources.