RAII (Resource Acquisition Is Initialization) ist ein aus C++ stammendes Idiom, bei dem die Lebenszeit einer Ressource strikt mit der Lebenszeit eines Objekts im Stack verknüpft ist. In Rust bildet dieses Konzept die Grundlage für das System der Besitztümer und der Freigabe von Ressourcen, was es ermöglicht, ohne klassische Garbage Collector (GC) auszukommen.
Viele Sprachen verwalten den Speicher und Ressourcen mit Hilfe eines Garbage Collectors, der periodisch "unnötige" Objekte bereinigt. Diese Strategie erhöht die Verzögerungen und gibt keine Garantie für die sofortige Freigabe externer Ressourcen (Dateien, Sockets usw.). In der niedrigleveligen und systemnahen Programmierung ist eine solche Situation inakzeptabel: Es bedarf Präzision und Determinismus bei der Ressourcenverwaltung.
In Rust besitzt jedes Objekt seine Ressource und gibt sie strikt bei der Zerstörung (out of scope) frei, durch den Aufruf von Drop (analog zum Destruktor). Infolgedessen werden Ressourcen sofort freigegeben, und alle Fehler der impliziten Freigabe werden auf ein Minimum reduziert. Das Typsystem und die Besitzverhältnisse in Rust verhindern Speicherlecks und doppelte Freigaben fast schon zur Kompilierzeit.
Beispielcode:
struct FileWrapper { file: std::fs::File, } impl Drop for FileWrapper { fn drop(&mut self) { println!("FileWrapper schließt die Datei! (scope exit)"); } } fn main() { let _fw = FileWrapper { file: std::fs::File::create("test.txt").unwrap() }; // Beim Verlassen von main wird drop garantiert aufgerufen }
Wesentliche Merkmale:
Wird Drop für Werte aufgerufen, die zuvor verschoben (moved) wurden?
Nein, nach der Verschiebung des Wertes wird Drop nur für den neuen Besitzer aufgerufen, das alte Objekt gilt als "leer" und Drop wird nicht ausgeführt.
let file1 = FileWrapper {...}; let file2 = file1; // file1 move // Drop wird einmal aufgerufen — für file2
Kann panic! oder unwrap() in der Mitte des Geltungsbereichs den Aufruf von drop verhindern?
Nein, eine Panik oder ein Fehlerausstieg annulliert nicht den Aufruf des Destruktors — Drop wird definitiv für alle Objekte, die aus dem Geltungsbereich ausgeschieden sind, aufgerufen.
Wenn ein Verweis ein Objekt besitzt, wird dann drop beim Ende der Lebensdauer des Verweises aufgerufen?
Nein, drop wird nur für den Besitzer des Objekts aufgerufen, Verweise besitzen nicht. Für Heap-Ressourcen wird ein Smart Pointer benötigt.
Der Entwickler hat einen Dateideskriptor durch einen Verweis an eine Schreibfunktion übergeben. Nach Abschluss des Programms blieb die Datei gesperrt, da drop nicht aufgerufen wurde (es gab keinen Besitzer, es wurde ein Verweis verwendet).
Vorteile:
Nachteile:
Das Besitzen von Ressourcen wurde immer durch Strukturen abgeschlossen, die Drop implementieren. Alle geöffneten Dateien, Verbindungen oder Locks werden automatisch bei Ausstieg aus dem Geltungsbereich oder bei einer Panik freigegeben. Ein Freifahrtschein für sicheres und triviales Ressourcenmanagement, selbst in komplexen Projekten.
Vorteile:
Nachteile: