Course contentsShow
← Rust
Lesson 265 of 1,9103. Borrowing and ReferencesFree lesson

Building Custom Smart Pointers

Create types that act as references with custom cleanup logic.

In this lesson, you will learn how to create custom types that act as smart pointers by wrapping a raw reference and triggering custom cleanup logic when they go out of scope.

The Power of Drop

A smart pointer is essentially a wrapper around a reference (or a raw pointer) that implements the Drop trait. While standard references like &T have their lifetimes managed automatically by the borrow checker, a custom smart pointer gives you control over the "exit" phase of the data’s life.

When your custom type goes out of scope, Rust automatically calls the drop method. This allows you to perform cleanup tasks—like logging access, releasing a hardware lock, or closing a file handle—while still letting the user interact with the underlying data as if it were a normal reference.

Implementing a Guard

Imagine you want a pointer that logs every time it is accessed and performs a cleanup task when it is destroyed. We use Deref to expose the underlying data and Drop to define our custom logic:

struct MyGuard<'a, T> {
    data: &'a T,
}

impl<'a, T> std::ops::Deref for MyGuard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        self.data
    }
}

impl<'a, T> Drop for MyGuard<'a, T> {
    fn drop(&mut self) {
        println!("Cleanup: The guard is being destroyed!");
    }
}

By wrapping a reference in MyGuard, you ensure that the moment the variable leaves its scope, your custom cleanup logic executes. Because we implemented Deref, you can pass MyGuard into any function expecting a &T, and it will behave exactly like a standard reference.

Why do this?

This pattern is fundamental for building RAII (Resource Acquisition Is Initialization) guards. By combining the lifetime 'a (to ensure the guard doesn't outlive the data) with the Drop trait, you create a robust interface that guarantees safety and cleanup without the user needing to call a manual "close" or "cleanup" function.

Key Takeaway: A custom smart pointer wraps a reference to extend its lifecycle behavior, using the Drop trait to execute custom logic automatically when the pointer exits its scope.