Resource Cleanup
When a value is no longer needed, Rust will run a "destructor" on that value. The most common way that a value is no longer needed is when it goes out of scope. This destructor calls Drop::drop
for that value, if the special Drop
trait is implemented for its type.
Release External Resources by Implementing the Drop
Trait
The Drop
↗ trait allows you to define custom behavior when your types go out of scope, such as releasing resources or performing cleanup tasks.
Its drop
method is called automatically when:
- A value goes out of scope (e.g., at the end of a function, a
let
↗ binding's scope, or a block). - A variable is re-assigned (and the old value is dropped).
- A collection (like a
Vec
) is dropped - its elements are also dropped.
Common use cases include:
- Releasing memory or resources: While Rust typically handles memory automatically,
Drop
is implemented by types that manage external resources, like file handles, network connections, mutex locks, or graphics contexts. When theDrop
implementation runs, it can close the files, disconnect sockets, unlock mutexes, etc. - Notifying external systems when an object is discarded.
- Logging.
- Implementing smart pointers: Types like
Box<T>
↗,Rc<T>
,String
andVec<T>
, rely heavily on theDrop
trait to manage their memory and resource deallocation. For instance,Rc<T>
usesDrop
to decrement its reference count and deallocate the data when the count reaches zero.
To implement Drop
for a custom type, you would do something like this:
struct CustomStruct { data: String, } impl Drop for CustomStruct { // This is the only method required by the Drop trait. It takes a mutable // reference to self. The code inside this method will be executed when // an instance of CustomStruct is dropped. fn drop(&mut self) { println!("Dropping CustomStruct with data `{}`!", self.data); } } fn main() { let _c = CustomStruct { data: String::from("my data"), }; let _d = CustomStruct { data: String::from("another data"), }; println!("CustomStructs created."); // c and d will be dropped automatically when they go out of scope here. let e = CustomStruct { data: String::from("explicit drop example"), }; println!("CustomStruct 'e' created."); // We can explicitly drop a value using `std::mem::drop`, but usually, // Rust handles it automatically. drop(e); println!("CustomStruct 'e' dropped before end of main."); println!("End of main."); }
Related Topics
- Data Structures.
- Generics.
- Ownership & Borrowing.
- Reference Counting.
- Smart Pointers.
- Traits.
- Vectors.