RAII (Resource Acquisition Is Initialization) is een idiom dat afkomstig is uit C++, waarbij de levensduur van een resource strikt verbonden is met de levensduur van een object op de stack. In Rust vormt dit concept de basis voor het systeem van eigendom en vrijgave van resources, wat het mogelijk maakt om zonder klassieke garbage collectors (GC) te werken.
Veel talen beheren geheugen en resources met behulp van een garbage collector, die periodiek "opruimt". Deze strategie verhoogt de latencies en biedt geen garanties voor onmiddellijke vrijgave van externe resources (bestanden, sockets, enz.). In laag-niveau en systeemprogrammering is zo'n situatie onacceptabel: precisie en determinisme in resourcebeheer zijn vereist.
In Rust bezit elk object zijn eigen resource en wordt deze strikt vrijgegeven bij de vernietiging (out of scope), via de aanroep van Drop (de analogon van een destructor). Hierdoor worden resources onmiddellijk vrijgegeven en worden alle fouten van impliciete vrijgave tot een minimum beperkt. Het type- en eigendomssysteem van Rust voorkomt lekken en dubbele vrijgave bijna al in de compilatiefase.
Voorbeeldcode:
struct FileWrapper { file: std::fs::File, } impl Drop for FileWrapper { fn drop(&mut self) { println!("FileWrapper sluit bestand! (scope exit)"); } } fn main() { let _fw = FileWrapper { file: std::fs::File::create("test.txt").unwrap() }; // Bij het verlaten van main, wordt drop gegarandeerd aangeroepen }
Belangrijke kenmerken:
Wordt Drop aangeroepen voor waarden die eerder zijn verplaatst (moved)?
_ Nee, na het verplaatsen van een waarde wordt Drop alleen aangeroepen voor de nieuwe eigenaar, de oude object wordt als "leeg" beschouwd en Drop wordt niet aangeroepen._
let file1 = FileWrapper {...}; let file2 = file1; // file1 move // Drop zal één keer worden aangeroepen — voor file2
Kan panic! of unwrap() in het midden van de scope het aanroepen van drop verhinderen?
_ Nee, een paniek of foutuitgang annuleert de aanroep van de destructor niet — Drop zal altijd worden aangeroepen voor alle objecten die uit de scope zijn gegaan._
Als een referentie het object bezit, wordt drop dan aangeroepen bij het beëindigen van de levensduur van de referentie?
_ Nee, drop wordt alleen aangeroepen voor de eigenaar van het object, referenties bezitten niet. Voor heap-resources is een smart pointer nodig._
Een ontwikkelaar gaf een bestandsdescriptor door als referentie aan een functie voor schrijven. Na het beëindigen van het programma bleef er een lock op het bestand, omdat drop niet werd aangeroepen (er was geen eigenaar, er werd een referentie gebruikt).
Voordelen:
Nadelen:
Eigendom van de resource werd altijd doorgegeven via structuren die Drop implementeerden. Alle geopende bestanden, verbindingen of locks worden automatisch vrijgegeven bij het beëindigen van de scope of bij paniek. Een vrijbrief voor veilige en triviale resourcebeheer, zelfs in complexe projecten.
Voordelen:
Nadelen: