Scope, Drop, and RAII
Worked examples
Read the claim, then run it and check the machine agrees. One at a time — nothing here is taken on trust.
struct Noisy { name: &'static str }
impl Drop for Noisy {
fn drop(&mut self) {
println!("dropping {}", self.name);
}
}
fn main() {
println!("before block");
{
let _n = Noisy { name: "inner" };
println!("inside block, still alive");
} // <- _n dropped HERE, deterministically
println!("after block");
}
The destructor runs at the inner }, not at program end and not
whenever a collector feels like it. Output, in order: before
block, inside block, still alive, dropping inner, after
block. The cleanup point is visible in the source — that's
deterministic destruction.
struct Noisy { name: &'static str }
impl Drop for Noisy {
fn drop(&mut self) {
println!("drop {}", self.name);
}
}
fn main() {
let _a = Noisy { name: "a" };
let _b = Noisy { name: "b" };
let _c = Noisy { name: "c" };
println!("end of main reached");
} // dropped in reverse: c, then b, then a
Three values in one scope drop in reverse declaration order.
Output: end of main reached, then drop c, drop b, drop a.
Last in, first out — so a value can safely depend on ones declared
before it, because those outlive it.
struct Guard { name: &'static str }
impl Drop for Guard {
fn drop(&mut self) {
println!("release {}", self.name);
}
}
fn main() {
let g = Guard { name: "lock" };
println!("holding {}", g.name);
drop(g); // destructor runs NOW; g is moved into drop() and retired
// println!("{}", g.name); // <- E0382: g was moved into drop()
println!("work after releasing the lock");
}
std::mem::drop(g) (in the prelude, so just drop(g)) forces the
destructor to run immediately — useful to release a lock or close a
file before scope end. It takes g by value, so g is moved and
can't be used afterward (the commented line is E0382). Output:
holding lock, release lock, work after releasing the lock.
Check the concept
One question at a time. Unsure? Revisit the lecture, then answer.
The challenge
Pass the quiz to unlock the challenge — your code will still be waiting here.