In this lesson, you will learn how to predict the exact order in which Rust cleans up your data when variables go out of scope, a skill vital for managing system resources like file handles or network sockets.
The LIFO Rule
Rust uses a "Last-In, First-Out" (LIFO) approach to resource destruction. When a scope ends (the closing curly brace }), Rust drops the variables declared within that scope in the exact reverse order of their declaration. This is a deliberate design choice: because later variables might depend on resources held by earlier ones, dropping them in reverse ensures that the "dependents" are cleaned up before the "dependencies" are invalidated.
Visualizing Destruction
Consider this scenario where we open a log file and a data processor:
struct Resource(String);
impl Drop for Resource {
fn drop(&mut self) {
println!("Dropping {}", self.0);
}
}
fn main() {
let _file = Resource(String::from("FileHandle"));
let _processor = Resource(String::from("Processor"));
println!("Scope ending...");
}
When this code runs, the output will be:
Scope ending...Dropping ProcessorDropping FileHandle
Even though _file was declared first, it is destroyed last. If _processor held a reference to the _file, this order guarantees that the processor is finished with the file before the file itself is closed.
Why This Matters
If you are managing hardware interfaces or database connections, you must be mindful of your declaration order. If Resource B relies on the state of Resource A, you should always declare Resource A first. This ensures that when the scope exits, Resource B is destroyed first, leaving Resource A available and valid until the very last moment. By controlling the order of declaration, you control the sequence of shutdown, preventing dangling references or premature resource release.
Key Takeaway: Rust destroys variables in the reverse order of their declaration, ensuring that dependent resources are cleaned up safely before their foundations.