Deref
- Rust course
- Intermediate
- Lesson 34/115
- 4 min
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 methodtype 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 → &strImplement 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
use std::ops::Deref;
fn main() {
// buraya yaz
}Sample solution
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
impl<T> Deref for Sarici<T> {
type ____ = T;
fn deref(&self) -> &T {
&self.0
}
}
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) |