capypad
0 day streak
rust / intermediate
Snippet

RAII and the Drop Trait for Resource Management

RAII (Resource Acquisition Is Initialization) ensures resources are properly released when objects go out of scope. The Drop trait defines cleanup logic that runs automatically when a value is dropped. In this example, FileGuard wraps a File and prints a message when dropped, guaranteeing cleanup even if an error occurs. Rust's ownership system ensures drop runs exactly once, eliminating double-free bugs.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use std::fs::File;
use std::io::Write;
use std::path::Path;
 
struct FileGuard {
filename: String,
file: Option<File>,
}
 
impl FileGuard {
fn new(name: &str) -> Result<Self, std::io::Error> {
let file = File::create(Path::new(name))?;
Ok(FileGuard {
filename: name.to_string(),
file: Some(file),
})
}
 
fn write(&mut self, content: &str) -> Result<(), std::io::Error> {
if let Some(ref mut f) = self.file {
f.write_all(content.as_bytes())?
}
Ok(())
}
}
 
impl Drop for FileGuard {
fn drop(&mut self) {
println!("Cleaning up: {}", self.filename);
self.file.take();
}
}
 
fn main() -> Result<(), std::io::Error> {
let guard = FileGuard::new("example.txt")?;
guard.write("Hello, Rust!")?;
println!("File written successfully");
Ok(())
}
Breakdown
1
impl Drop for FileGuard
Drop trait is automatically called when FileGuard goes out of scope
2
self.file.take();
take() replaces Some with None, ensuring File is closed and preventing double-drop
3
guard.write("Hello, Rust!")?;
If write fails, ? propagates error but guard still drops correctly
4
println!("File written successfully");
Guaranteed cleanup happens after this line completes