← Back to Rust Course | Chapter 13: Smart Pointers & Unsafe | Lesson 5 of 7

The Drop Trait

Drop is a special goodbye method Rust calls automatically right before a value disappears for good.

Implementing Drop

Implementing the Drop trait's drop method lets a type execute custom cleanup code automatically the moment its value's scope ends.

Example: Implementing Drop

markup
struct Logger {
    name: String,
}

impl Drop for Logger {
    fn drop(&mut self) {
        println!("Logger '{}' shutting down", self.name);
    }
}

fn main() {
    let _logger = Logger { name: String::from("main-logger") };
    println!("Logger is active");
}

Forcing an Early Drop

Since calling .drop() directly is disallowed by the compiler, std::mem::drop(value) is used to force a value to be cleaned up earlier than the end of its natural scope.

Example: Forcing an Early Drop

markup
struct Resource;

impl Drop for Resource {
    fn drop(&mut self) {
        println!("Resource cleaned up");
    }
}

fn main() {
    let res = Resource;
    println!("About to drop early");
    drop(res);
    println!("Dropped; continuing");
}

Drop Order Matches Reverse Declaration

When several values with Drop implementations go out of scope together, they are cleaned up in the reverse order they were declared, similar to unwinding a stack.

Example: Drop Order Matches Reverse Declaration

markup
struct Item(i32);

impl Drop for Item {
    fn drop(&mut self) {
        println!("Dropping item {}", self.0);
    }
}

fn main() {
    let _a = Item(1);
    let _b = Item(2);
    let _c = Item(3);
    println!("All items created");
}

A Practical Use: Resource Cleanup

Drop is commonly used to guarantee cleanup logic, like closing a connection, always runs -- even if the function returns early -- since the value is dropped whenever its scope ends.

Example: A Practical Use: Resource Cleanup

markup
struct Connection {
    id: u32,
}

impl Drop for Connection {
    fn drop(&mut self) {
        println!("Closing connection #{}", self.id);
    }
}

fn use_connection() {
    let _conn = Connection { id: 7 };
    println!("Using connection #7");
}

fn main() {
    use_connection();
    println!("Connection was closed automatically");
}
Common Mistakes
  1. Trying to call .drop() directly on a value -- Rust forbids this explicitly and provides std::mem::drop instead.
  2. Assuming Drop::drop runs immediately when a value is moved -- it only runs when the value's owner truly goes out of scope.
  3. Forgetting values are dropped in reverse declaration order within the same scope, which can matter for cleanup ordering.
Chapter Summary
  • Implementing Drop lets a type run custom cleanup logic automatically when its value goes out of scope.
  • You cannot call the drop method directly; use the free function std::mem::drop(value) to force an early drop.
  • Values are dropped in reverse order of their declaration within a scope.
  • Drop is commonly used for releasing resources like file handles, locks, or network connections.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.