RAII (Resource Acquisition Is Initialization) is an idiom that originated in C++, where the lifetime of a resource is tightly bound to the lifetime of an object in the stack. In Rust, this concept forms the basis of the ownership and resource deallocation system, allowing it to operate without classic garbage collectors (GC).
Many languages manage memory and resources using garbage collectors, which periodically "clean up" unnecessary objects. This strategy introduces latency and does not guarantee immediate deallocation of external resources (files, sockets, etc.). In low-level and systems programming, such situations are unacceptable: precision and determinism in resource management are required.
In Rust, every object owns its resource and deallocates it strictly at the place of destruction (out of scope), through the call to Drop (analogous to a destructor). As a result, resources are freed immediately, and all errors related to implicit deallocation are minimized. Rust’s type and ownership system prevents leaks and double deallocation almost at compile-time.
Example code:
struct FileWrapper { file: std::fs::File, } impl Drop for FileWrapper { fn drop(&mut self) { println!("FileWrapper closing the file! (scope exit)"); } } fn main() { let _fw = FileWrapper { file: std::fs::File::create("test.txt").unwrap() }; // On exiting main, drop is guaranteed to be called }
Key features:
Is Drop called for values that were moved earlier?
No, after a value is moved, Drop is called only for the new owner, while the old object is considered "empty" and Drop is not triggered.
let file1 = FileWrapper {...}; let file2 = file1; // file1 move // Drop will be called only once — for file2
Can panic! or unwrap() in the middle of the scope prevent drop from being called?
No, panic or exit on error does not cancel the destructor call — Drop will be called for all objects that have gone out of scope.
If a reference owns an object, will drop be called at the end of the reference's lifetime?
No, drop is called only for the owner of the object; references do not own. For heap resources, a smart pointer is needed.
A developer passed a file descriptor by reference to a write function. After the program finished running, the file remained locked because drop was not called (there was no owner, only a reference was used).
Pros:
Cons:
Ownership of the resource was always transferred by structures implementing Drop. All open files, connections, or locks are automatically released upon the completion of the scope or panic, providing a safe and trivial resource management even in complex projects.
Pros:
Cons: