Rust Lang

Rust Destructor

Rust provides a mechanism to provide cleanup on the heap. The drop trait in Rust allows you to run a “destructor” when a value is no longer needed. A common case is if a value goes out of scope.

The rust destructor is comprised of two components:

  1. A call to Drop::drop if the Drop trait is implemented by the value type.
  2. An auto-generated drop that recursively calls the destructor on the field of the value. This removes the need for you to keep calling the destructor.

Rust types such as Box, Vec, String, File and Processes implement the Drop trait by default to free the resources.

Implementing Rust Drop Trait

Let us see how we can implement a trait for a custom type.

The syntax for drop trait is as shown:

trait Drop {

fn Drop(&mut self);

}

As mentioned, rust will automatically drop a value if it goes out of scope. This is done in reverse order of creation.

Take example below that implements a drop trait for a custom type.

use std::thread;
use std::time::Duration;
structUser {
    username: & 'static str,
}
impl Drop for User {
fndrop(&mutself) {
println!("Dropping {}", self.username);
    }
}
fnmain() {
    // scope 1
let _user1 = User {username: "username1"};
     {
         // scope 2
let _user2 = User {username: "username2"};
         {
             // scope 3
let _user3 = User{username: "username3"};
let _user4 = User{username: "username4"};

println!("Exiting scope 3");
        }
println!("Exited scope 3");
println!("------------------------------------------------");

        // wait
        thread::sleep(Duration::from_millis(1500));
println!("Exiting scope 2");
     }
println!("Exited scope 2");
println!("------------------------------------------------");
     // drop variable manually
     thread::sleep(Duration::from_millis(1500));
     drop(_user1);
println!("Main function close!");
println!("------------------------------------------------");
}

If we run the code above, we should see an output as shown below:

Let us explain what the code above is doing. We start by defining a custom type using a struct. Note that we specify the username field to have a static lifetime.

Next, we define a drop trait for the User type. This is a simple drop trait that simply prints to the console when a variable is being dropped after it goes out of scope.

In the main function, we create an instance of the User struct called “user1”.

We then create two new blocks which contain their own scope and define variables in each scope.

Note the println message that describes when we are going out of scope and when a variable is dropped.

We also implement a sleep duration to illustrate the switch between scopes.

Finally, we manually drop the variable in the main scope using the drop function as defined in the Drop trait.

Conclusion

This short article illustrates how to implement the drop trait for custom types and how drop works when a variable goes out of scope.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list