Der Trait Drop ermöglicht es, benutzerdefinierte Bereinigungslogik für eine Ressource beim Verlassen des Gültigkeitsbereichs festzulegen. Er wird normalerweise verwendet, um Dateien, Netzwerke, externe und unsichere Ressourcen freizugeben. Drop wird automatisch vom Compiler aufgerufen.
Beispiel:
struct FileWrapper { fd: i32, } impl Drop for FileWrapper { fn drop(&mut self) { println!("Schließe fd: {}", self.fd); unsafe { libc::close(self.fd); } } } fn main() { let file = FileWrapper { fd: 42 }; } // drop wird automatisch aufgerufen
Besonderheiten:
file.drop() aufgerufen werden, aber man kann ihn mit std::mem::drop(file) aufrufen.panic!) innerhalb von drop ausgelöst werden — dies führt zu "double panic" und einem Absturz des Prozesses.Frage: Was passiert, wenn versucht wird, während des drop() einer Struktur den Besitz einer Ressource an einen anderen Teil des Programms zu übertragen — zum Beispiel, sie aus dem drop zurückzugeben?
Antwort: Es ist nicht möglich, einen Wert eines Strukturfeldes während des drops an jemand anderen als den Drop selbst zu "retten" oder zu übertragen; der Versuch, einen Wert zurückzugeben oder zu übertragen, führt zu einem Compilerfehler oder einem Speichersicherheitsproblem (wenn unsafe verwendet wird). Beispiel für einen Fehler:
impl Drop for MyStruct { fn drop(&mut self) -> T { // Fehler: Drop::drop kann keinen Wert zurückgeben! ... } }
Geschichte
In einem Dateiprocessor wurde vergessen, Drop für eine Struktur, die direkt einen rohen Dateideskriptor umschließt, zu implementieren. Nach Hunderten von Operationen trat "Dateideskriptorlimit erreicht" auf — die Ressourcen wurden nicht freigegeben.
Geschichte
In einer Netzwerkbibliothek wurde Drop für die Wrapper um eine TCP-Verbindung implementiert, aber bei drop kam es zu einem Panic aufgrund eines Fehlers beim Schließen des Sockets. Dies führte zu einem Absturz des Threads wegen double-panic (der einzige Weg — vermeide Panic in Drop!).
Geschichte
In einem Plug-in-System wurde versucht, die Bereinigung mit Hilfe von Drop zu implementieren, indem während des drops neue Ressourcen erstellt wurden (z. B. Protokollierung in eine Datei). Dies führte zu "bereits ausgeliehen: BorrowMutError" aufgrund rekursiver drop-Aufrufe für verbundene Strukturen und Ressourcenlecks.