---
title: "Deref e DerefMut Traits em Rust"
url: "https://rustlang.com.br/stdlib/deref/"
markdown_url: "https://rustlang.com.br/stdlib/deref.MD"
description: "Guia completo sobre Deref e DerefMut em Rust: smart pointers, deref coercion, String para \u0026str, Vec para slice e exemplos."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Deref e DerefMut Traits em Rust

Guia completo sobre Deref e DerefMut em Rust: smart pointers, deref coercion, String para &str, Vec para slice e exemplos.


## O que são Deref e DerefMut?

Os traits `Deref` e `DerefMut` controlam o comportamento do operador de dereferência (`*`). Eles são a base do sistema de **smart pointers** do Rust e habilitam o mecanismo de **deref coercion** — uma das conveniências mais poderosas da linguagem.

- **`Deref`**: permite que `*valor` retorne uma referência ao tipo interno. Habilita coerção automática de `&T` para `&U`.
- **`DerefMut`**: extensão mutável de `Deref`. Permite que `*valor` retorne uma referência mutável.

Graças a `Deref`, você pode passar um `&String` onde um `&str` é esperado, ou um `&Vec<T>` onde um `&[T]` é esperado — tudo automaticamente.

---

## Definição dos Traits

```rust
// std::ops::Deref
pub trait Deref {
    type Target: ?Sized;
    fn deref(&self) -> &Self::Target;
}

// std::ops::DerefMut
pub trait DerefMut: Deref {
    fn deref_mut(&mut self) -> &mut Self::Target;
}
```

O tipo associado `Target` define para qual tipo a dereferência resolve. Por exemplo:
- `String` implementa `Deref<Target = str>`
- `Vec<T>` implementa `Deref<Target = [T]>`
- `Box<T>` implementa `Deref<Target = T>`

---

## Deref Coercion: A Mágica por trás dos Bastidores

Deref coercion é a conversão automática que o compilador aplica quando um tipo que implementa `Deref` é passado por referência. As regras são:

1. `&T` → `&U` quando `T: Deref<Target = U>`
2. `&mut T` → `&mut U` quando `T: DerefMut<Target = U>`
3. `&mut T` → `&U` quando `T: Deref<Target = U>` (mutável para imutável)

A coerção **nunca** vai de `&T` para `&mut U` — isso violaria as regras de borrowing.

```rust
fn imprimir_tamanho(s: &str) {
    println!("Tamanho: {}", s.len());
}

fn somar_slice(numeros: &[i32]) -> i32 {
    numeros.iter().sum()
}

fn main() {
    let texto = String::from("Rust Brasil");
    let numeros = vec![1, 2, 3, 4, 5];

    // Deref coercion: &String → &str
    imprimir_tamanho(&texto);

    // Deref coercion: &Vec<i32> → &[i32]
    let soma = somar_slice(&numeros);
    println!("Soma: {}", soma);

    // Também funciona com Box
    let boxed = Box::new(String::from("Boxed String"));
    // Box<String> → String → str (cadeia de deref)
    imprimir_tamanho(&boxed);
}
```

---

## Como Implementar

### Implementando Deref para um tipo wrapper

```rust
use std::ops::Deref;

struct MeuVec<T> {
    interno: Vec<T>,
    nome: String,
}

impl<T> MeuVec<T> {
    fn novo(nome: impl Into<String>) -> Self {
        MeuVec {
            interno: Vec::new(),
            nome: nome.into(),
        }
    }

    fn push(&mut self, valor: T) {
        self.interno.push(valor);
    }

    fn nome(&self) -> &str {
        &self.nome
    }
}

impl<T> Deref for MeuVec<T> {
    type Target = Vec<T>;

    fn deref(&self) -> &Vec<T> {
        &self.interno
    }
}

fn main() {
    let mut v = MeuVec::novo("minha lista");
    v.push(1);
    v.push(2);
    v.push(3);

    // Métodos de Vec disponíveis via Deref
    println!("Tamanho: {}", v.len());       // Vec::len()
    println!("Primeiro: {:?}", v.first());  // slice::first()
    println!("Nome: {}", v.nome());         // MeuVec::nome()

    // Iteração funciona via Deref para &[T]
    for item in v.iter() {
        println!("{}", item);
    }
}
```

### Implementando Deref e DerefMut

```rust
use std::ops::{Deref, DerefMut};
use std::fmt;

#[derive(Debug)]
struct Validado<T: fmt::Debug> {
    valor: T,
    modificado: bool,
}

impl<T: fmt::Debug> Validado<T> {
    fn novo(valor: T) -> Self {
        Validado {
            valor,
            modificado: false,
        }
    }

    fn foi_modificado(&self) -> bool {
        self.modificado
    }
}

impl<T: fmt::Debug> Deref for Validado<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.valor
    }
}

impl<T: fmt::Debug> DerefMut for Validado<T> {
    fn deref_mut(&mut self) -> &mut T {
        self.modificado = true;  // Rastreia modificações!
        &mut self.valor
    }
}

fn main() {
    let mut nome = Validado::novo(String::from("Ana"));

    // Deref: acessa métodos de String (imutável)
    println!("Tamanho: {}", nome.len());
    println!("Modificado? {}", nome.foi_modificado()); // false

    // DerefMut: modifica o valor interno
    nome.push_str(" Silva");
    println!("Nome: {}", *nome);
    println!("Modificado? {}", nome.foi_modificado()); // true
}
```

---

## Exemplos Práticos

### Exemplo 1: A cadeia de dereferência (Deref chaining)

O compilador aplica deref coercion repetidamente até encontrar o tipo esperado:

```rust
use std::rc::Rc;

fn contar_caracteres(s: &str) -> usize {
    s.chars().count()
}

fn main() {
    let texto = String::from("café");

    // Cadeia de 1 nível: &String → &str
    let n1 = contar_caracteres(&texto);

    // Cadeia de 2 níveis: &Box<String> → &String → &str
    let boxed = Box::new(texto.clone());
    let n2 = contar_caracteres(&boxed);

    // Cadeia de 3 níveis: &Rc<Box<String>> → &Box<String> → &String → &str
    let rc = Rc::new(Box::new(texto));
    let n3 = contar_caracteres(&rc);

    println!("{} {} {}", n1, n2, n3); // 4 4 4
}
```

### Exemplo 2: Smart pointer personalizado com contagem de acessos

```rust
use std::ops::Deref;
use std::cell::Cell;

struct Rastreado<T> {
    valor: T,
    acessos: Cell<u64>,
}

impl<T> Rastreado<T> {
    fn novo(valor: T) -> Self {
        Rastreado {
            valor,
            acessos: Cell::new(0),
        }
    }

    fn total_acessos(&self) -> u64 {
        self.acessos.get()
    }
}

impl<T> Deref for Rastreado<T> {
    type Target = T;

    fn deref(&self) -> &T {
        self.acessos.set(self.acessos.get() + 1);
        &self.valor
    }
}

fn main() {
    let dados = Rastreado::novo(vec![10, 20, 30, 40, 50]);

    // Cada acesso via Deref incrementa o contador
    println!("Tamanho: {}", dados.len());          // acesso 1
    println!("Primeiro: {:?}", dados.first());     // acesso 2
    println!("Contém 30? {}", dados.contains(&30)); // acesso 3

    println!("Total de acessos: {}", dados.total_acessos()); // 3
}
```

### Exemplo 3: Deref com o newtype pattern

```rust
use std::ops::Deref;
use std::fmt;

struct Nome(String);

impl Deref for Nome {
    type Target = str;

    fn deref(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for Nome {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // self automaticamente faz deref para &str
        write!(f, "{}", &**self)
    }
}

impl Nome {
    fn novo(nome: impl Into<String>) -> Result<Self, String> {
        let nome = nome.into();
        if nome.trim().is_empty() {
            Err("Nome não pode ser vazio".to_string())
        } else {
            Ok(Nome(nome))
        }
    }
}

fn cumprimentar(nome: &str) {
    println!("Olá, {}!", nome);
}

fn main() {
    let nome = Nome::novo("Maria").unwrap();

    // Deref coercion: &Nome → &str
    cumprimentar(&nome);

    // Métodos de str disponíveis
    println!("Maiúsculo: {}", nome.to_uppercase());
    println!("Tamanho: {}", nome.len());
    println!("Começa com 'M'? {}", nome.starts_with('M'));
}
```

### Exemplo 4: String, Vec e Box — os Deref da stdlib

```rust
fn main() {
    // String: Deref<Target = str>
    let s = String::from("Rust é incrível");
    let fatia: &str = &s;  // Deref coercion
    println!("{}", fatia);

    // Vec<T>: Deref<Target = [T]>
    let v = vec![1, 2, 3, 4, 5];
    let slice: &[i32] = &v;  // Deref coercion
    println!("{:?}", slice);

    // Métodos de slice disponíveis em Vec via Deref
    println!("Janelas de 3:");
    for janela in v.windows(3) {
        println!("  {:?}", janela);
    }

    // Box<T>: Deref<Target = T>
    let b = Box::new(42);
    let valor: &i32 = &b;  // Deref coercion
    println!("Boxed: {}", valor);

    // Box<dyn Trait> também funciona
    let texto: Box<dyn std::fmt::Display> = Box::new("olá");
    println!("{}", texto);
}
```

### Exemplo 5: DerefMut na prática

```rust
use std::ops::{Deref, DerefMut};

struct LogVec<T> {
    dados: Vec<T>,
}

impl<T: std::fmt::Debug> LogVec<T> {
    fn novo() -> Self {
        LogVec { dados: Vec::new() }
    }
}

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

impl<T: std::fmt::Debug> DerefMut for LogVec<T> {
    fn deref_mut(&mut self) -> &mut Vec<T> {
        &mut self.dados
    }
}

fn main() {
    let mut lista = LogVec::novo();

    // DerefMut: métodos mutáveis de Vec
    lista.push(1);
    lista.push(2);
    lista.push(3);

    // Deref: métodos imutáveis
    println!("Tamanho: {}", lista.len());
    println!("Dados: {:?}", *lista);

    // sort está disponível via DerefMut → &mut [T]
    lista.sort();
    lista.reverse();
    println!("Invertido: {:?}", *lista); // [3, 2, 1]
}
```

---

## Padrões e Boas Práticas

1. **Implemente Deref apenas para smart pointers**: `Deref` é projetado para tipos que encapsulam outro tipo (como `Box`, `Rc`, `Arc`). Não use para relações "tem um" arbitrárias.

2. **Deref não substitui herança**: Embora deref coercion pareça herança, o propósito é diferente. Use traits para polimorfismo, não Deref.

3. **Prefira `AsRef` para funções genéricas**: Se você quer que uma função aceite tanto `String` quanto `&str`, use `AsRef<str>` como bound em vez de depender de deref coercion. Veja [AsRef e Borrow](/stdlib/asref-borrow/).

4. **DerefMut pode ter efeitos colaterais**: Como no exemplo do tipo `Validado`, `deref_mut` pode rastrear modificações. Use com cuidado.

5. **Cuidado com ambiguidade de métodos**: Se seu tipo e o `Target` têm um método com o mesmo nome, o método do tipo tem prioridade. Use `(*valor).metodo()` para forçar o acesso via Deref.

6. **Deref é transitivo**: O compilador aplica deref coercion em cadeia (`Rc<Box<String>>` → `Box<String>` → `String` → `str`), mas isso pode dificultar a leitura do código.

---

## Veja Também

- [AsRef, AsMut e Borrow](/stdlib/asref-borrow/) — alternativas a Deref para funções genéricas
- [Operator Overloading: std::ops](/stdlib/ops-traits/) — Deref faz parte do módulo std::ops
- [Box<T>](/stdlib/box-t/) — o smart pointer mais simples, implementa Deref
- [String](/stdlib/string/) — implementa Deref<Target = str>
