Rust Drop Trait
Drop trait
- When a value leaves the scope, the drop trait is used to release resources like files or network connections.
- The space on the heap that the Box<T> points to is dealt with using the Drop trait.
- The drop() method, which accepts a mutable reference to the self, is implemented using the drop trait.
Example:
struct Example
{
a : i32,
}
impl Drop for Example
{
fn drop(&mut self)
{
println!("Dropping the instance of Example with data : {}", self.a);
}
}
fn main()
{
let a1 = Example{a : 10};
let b1 = Example{a: 20};
println!("Instances of Example type are created");
}
Output:
Instances of Example type are created
Dropping the instance of Example with data : 20
Dropping the instance of Example with data : 10
Program Explanation
- The Drop trait has been implemented on the type Example, and the drop() method has been defined within the Drop trait implementation.
- We generate instances of the type Example inside the main() method, and instances exit the scope at the end of the function.
- Rust invokes the drop() function implicitly to remove instances of type Example when they leave the scope. It will discard the b1 instance first, followed by the a1 instance.
Dropping a value early with std::mem::drop
There are situations when dropping the value before the scope expires becomes necessary. The std::mem::drop method is used to drop the value early if that is our preference.
Example:
struct Example
{
a : String,
}
impl Drop for Example
{
fn drop(&mut self)
{
println!("Dropping the instance of Example with data : {}", self.a);
}
}
fn main()
{
let a1 = Example{a : String::from("Hello")};
a1.drop();
let b1 = Example{a: String::from("World")};
println!("Instances of Example type are created");
}
Output:
We manually invoke the drop() method in the example above. We are not permitted to explicitly invoke the drop() method, the Rust compiler complains. To drop the item before it exits the scope, we use the std::mem::drop function rather than the drop() method directly.
The drop() function described in the Drop trait has a different syntax than the one found in the std::mem::drop function. The value supplied as an input to the std::mem::drop function must be dropped before it exits the scope.
Example:
struct Example
{
a : String,
}
impl Drop for Example
{
fn drop(&mut self)
{
println!("Dropping the instance of Example with data : {}", self.a);
}
}
fn main()
{
let a1 = Example{a : String::from("Hello")};
drop(a1);
let b1 = Example{a: String::from("World")};
println!("Instances of Example type are created");
}
Output:
Dropping the instance of Example with data : Hello
Instances of Example type are created
Dropping the instance of Example with data : World
The a1 object is destroyed in the example above by sending it as an input to the drop(a1) function.