CodeBlanks Logo Icon CodeBlanks

Deref

Learn automatic reference resolution with the Deref trait.

Deref

The Deref trait determines how a type behaves with the * operator. This is what lets smart pointers be used "like the value they hold":

use std::ops::Deref;

struct Sarici<T>(T);

impl<T> Deref for Sarici<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

let s = Sarici(String::from("Ece"));
println!("{}", s.len());   // 3: String's method

type Target is the trait's associated type: it says which type you get when dereferencing.

Chained conversion

Deref coercion works in a chain and has no runtime cost:

fn selam(ad: &str) -> String {
    format!("Merhaba {ad}")
}

let s = Sarici(String::from("Ece"));
println!("{}", selam(&s));   // &Sarici<String> → &String → &str

Implement Deref only for smart-pointer-like types; adding it to an ordinary struct creates "hidden" behaviour and hurts readability. The mutable version is DerefMut.

Practice Wrapper

Implement Deref for the Sarici<T> type above and write fn selam(ad: &str) -> String. For Sarici(String::from("Ece")), print the result of selam(&s) and the value of s.len() separated by a space.

Starter code

main.rs
use std::ops::Deref;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::ops::Deref;

struct Sarici<T>(T);

impl<T> Deref for Sarici<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

fn selam(ad: &str) -> String {
    format!("Merhaba {ad}")
}

fn main() {
    let s = Sarici(String::from("Ece"));
    println!("{} {}", selam(&s), s.len());
}

Expected output

Merhaba Ece 3

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does deref coercion do?

  • Only works for Box
  • Automatically converts references like &Sarici<String> → &String → &str Correct answer
  • Copies the value
  • Moves ownership

Explanation: The compiler adds the deref chain until it reaches the expected type; that's why a &String can be passed where &str is expected.

2 Associated type

Question
impl<T> Deref for Sarici<T> {
    type ____ = T;
    fn deref(&self) -> &T {
        &self.0
    }
}
Answer
impl<T> Deref for Sarici<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

Explanation: The Deref trait's associated type is Target.

3 Type and Target

Term Meaning
Box<T> T
String str
Vec<T> [T]
Rc<T> T (shared)

All lessons in Intermediate