Drop

RecipeCrates
std

Release External Resources by Implementing the Drop Trait

std

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 by Rust 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 the Drop 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 and Vec, rely heavily on the Drop trait to manage their memory and resource deallocation. For instance, Rc<T> uses Drop 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,
    // you let Rust handle it automatically.
    drop(e);
    println!("CustomStruct 'e' dropped before end of main.");

    println!("End of main.");
}

Related Topics

  • Data Structures.
  • Generics.
  • Memory Management.
  • Ownership & Borrowing.
  • Reference Counting.
  • Smart Pointers.
  • Traits.
  • Vectors.