De trait Drop stelt je in staat om aangepaste opruimlogica voor een resource in te stellen wanneer deze uit de zichtbaarheid verdwijnt. Dit wordt meestal gebruikt voor het vrijgeven van bestands-, netwerk-, externe en onveilige resources. Drop wordt automatisch door de compiler aangeroepen.
Voorbeeld:
struct FileWrapper { fd: i32, } impl Drop for FileWrapper { fn drop(&mut self) { println!("Sluiten fd: {}", self.fd); unsafe { libc::close(self.fd); } } } fn main() { let file = FileWrapper { fd: 42 }; } // drop wordt automatisch aangeroepen
Bijzonderheden:
file.drop(), maar je kunt het aanroepen via std::mem::drop(file).panic!) binnen drop moet worden vermeden — dit leidt tot "double panic" en een gefaalde beëindiging van het proces.Vraag: Wat gebeurt er als je probeert het eigendom van een resource naar een andere plaats in het programma over te dragen tijdens de drop() van een structuur — bijvoorbeeld, het retourneren ervan uit drop?
Antwoord: Je kunt geen waarde uit een veld van een structuur "redden" of doorgeven aan iemand anders tijdens drop, behalve aan de drop zelf; poging om een waarde terug te geven of deze door te geven resulteert in een compilerfout of schending van geheugensbeveiliging (wanneer unsafe wordt gebruikt). Voorbeeld van een fout:
impl Drop for MyStruct { fn drop(&mut self) -> T { // Fout: Drop::drop kan geen waarde retourneren! ... } }
Verhaal
In een bestandprocessor vergaten ze Drop te implementeren voor een structuur die een ruwe bestandsdescriptor direct omhulde. Na honderden bewerkingen ontstond er een "uitputting van de limiet van bestandsdescriptors" — resources werden niet opgekuist.
Verhaal
In een netwerkbibliotheek implementeerden ze Drop voor een wrapper rond een TCP-verbinding, maar tijdens drop vond er een panic plaats door een fout bij het sluiten van de socket. Dit leidde tot een gefaalde beëindiging van de thread bij een double-panic (de enige manier — panikeren vermijden in Drop!).
Verhaal
In een plug-in systeem probeerden ze opruimen te implementeren met behulp van Drop, waarbij ze nieuwe resources creëerden tijdens drop (bijvoorbeeld loggen naar een bestand). Dit leidde tot "al gerecycled: BorrowMutError" door de recursieve aanroep van drop voor gerelateerde structuren en resourcelekken.