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

The Deref Trait

Deref teaches a wrapper type how to act like the value it's holding, so you can use it almost as if it wasn't wrapped at all.
Syntax
rust
impl Deref for Name {
    type Target = Inner;

    fn deref(&self) -> &Self::Target {
        &self.field
    }
}

Box Already Implements Deref

Box<T> implements Deref, which is why *boxed_value gives you the inner value directly, even though Box itself is a distinct type.

Example: Box Already Implements Deref

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `boxed`, set to `Box::new(5)`
    let boxed = Box::new(5);
    // Print "Dereferenced: {}" to the console, substituting in `*boxed` (with a trailing newline)
    println!("Dereferenced: {}", *boxed);
}

Implementing Deref for a Custom Wrapper

You can implement Deref for your own wrapper struct, defining what *wrapper should produce and enabling deref coercion for method calls.

Example: Implementing Deref for a Custom Wrapper

markup
// Bring `std::ops::Deref` into scope
use std::ops::Deref;

// Define a struct `MyBox` to group related fields together
struct MyBox<T>(T);

// Implement the `Deref` trait for `MyBox`
impl<T> Deref for MyBox<T> {
    type Target = T;
    // Define the function `deref` taking `&self` and returning a `&T`
    fn deref(&self) -> &T {
        &self.0
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `wrapped`, set to `MyBox(String::from("wrapped value"))`
    let wrapped = MyBox(String::from("wrapped value"));
    // Print "{}" to the console, substituting in `*wrapped` (with a trailing newline)
    println!("{}", *wrapped);
}

Deref Coercion in Method Calls

When calling a method, Rust automatically applies deref coercion, converting &MyBox<String> into &str as needed, so you can call String/str methods directly on the wrapper.

Example: Deref Coercion in Method Calls

markup
// Bring `std::ops::Deref` into scope
use std::ops::Deref;

// Define a struct `MyBox` to group related fields together
struct MyBox<T>(T);

// Implement the `Deref` trait for `MyBox`
impl<T> Deref for MyBox<T> {
    type Target = T;
    // Define the function `deref` taking `&self` and returning a `&T`
    fn deref(&self) -> &T {
        &self.0
    }
}

// Define the function `print_len` taking `s`
fn print_len(s: &str) {
    // Print "Length: {}" to the console, substituting in `s.len()` (with a trailing newline)
    println!("Length: {}", s.len());
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `wrapped`, set to `MyBox(String::from("coerced"))`
    let wrapped = MyBox(String::from("coerced"));
    print_len(&wrapped);
}

DerefMut for Mutable Access

Implementing DerefMut alongside Deref allows mutable dereferencing (*wrapper = ... or calling &mut self methods) through the wrapper type as well.

Example: DerefMut for Mutable Access

markup
// Bring `std::ops::{Deref, DerefMut}` into scope
use std::ops::{Deref, DerefMut};

// Define a struct `MyBox` to group related fields together
struct MyBox<T>(T);

// Implement the `Deref` trait for `MyBox`
impl<T> Deref for MyBox<T> {
    type Target = T;
    // Define the function `deref` taking `&self` and returning a `&T { &self.0 }`
    fn deref(&self) -> &T { &self.0 }
}

// Implement the `DerefMut` trait for `MyBox`
impl<T> DerefMut for MyBox<T> {
    // Define the function `deref_mut` taking `self` and returning a `&mut T { &mut self.0 }`
    fn deref_mut(&mut self) -> &mut T { &mut self.0 }
}

// Entry point: execution of the program starts here
fn main() {
    // Declare a mutable variable `wrapped`, initialized to `MyBox(10)`
    let mut wrapped = MyBox(10);
    *wrapped += 5;
    // Print "{}" to the console, substituting in `*wrapped` (with a trailing newline)
    println!("{}", *wrapped);
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting Deref only affects how *value and method calls behave -- it does not change the wrapper's own type identity.
  2. Assuming implementing Deref also gives you DerefMut automatically -- mutable dereferencing requires a separate trait implementation.
  3. Overusing custom Deref implementations to fake inheritance-like behavior, which can make code confusing to follow.
Chapter Summary
  • Implementing Deref lets a custom type be dereferenced with *, similar to how Box<T> works.
  • Deref coercion automatically converts &MyType into &InnerType when calling methods, reducing manual dereferencing.
  • DerefMut is the corresponding trait for mutable dereferencing and must be implemented separately.
  • Deref is what allows smart pointers like Box, Rc, and custom wrapper types to be used almost like their inner value.
🔒

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.