Destructor

From Rust Community Wiki
(Redirected from Drop)

A destructor is a function that is run when a value is destroyed. Destructors are often used to free resources (e.g. heap memory) that are no longer required when a value is destroyed.

Values are destroyed when they are dropped, which usually happens when they go out of scope (at the end of the enclosing curly braces {}). Static items are never dropped. Most types don't have a destructor; when they are dropped, nothing happens.

In Rust, destructors are defined by implementing the DropThis links to official Rust documentation trait. Note that even types that don't implement Drop can have a destructor. For example, Option<Box<()>> doesn't implement Drop, but it has a destructor that deallocates the inner Box, if present. This is called a drop glue.

Example[edit]

struct Foo;

impl std::ops::Drop for Foo {
    fn drop(&mut self) {
        println!("Foo was dropped.");
    }
}


This prints "Foo was dropped." every time the a Foo instance is dropped.

Use cases[edit]

Freeing memory, file descriptors, and other resources[edit]

This is the original, intended use case for destructors, as their name indicates. They are involved in the "destruction" of the resource represented by an object.

This can be seen in its simplest form in BoxThis links to official Rust documentation, which has a destructor that simply frees memory, but can also be seen in more complicated forms such as RcThis links to official Rust documentation (which sometimes frees memory, but sometimes only adjusts a number), and FileThis links to official Rust documentation, which closes as file descriptor.

Locking and other forms of exclusive access[edit]

Since it is impossible to use an object after its destructor runs, the destructor can also be used as a way to design a sound abstraction around mutual exclusion, as shown in the standard library MutexThis links to official Rust documentation API.

To make this work, locking a Mutex returns a MutexGuardThis links to official Rust documentation handle that acts like a smart pointer for the locked object, and the destructor unlocks it. Since it is impossible to use the guard after the destructor runs, and it is impossible to acquire a guard without calling the lock(&self) function, the value protected by the Mutex can never be accessed without holding the lock.

The same pattern can be found in other APIs, such as RwLockThis links to official Rust documentation and RefCellThis links to official Rust documentation.

Impact on non-lexical lifetimes[edit]

TODO