---
title: "Default Trait em Rust"
url: "https://rustlang.com.br/stdlib/default/"
markdown_url: "https://rustlang.com.br/stdlib/default.MD"
description: "Guia completo sobre o trait Default em Rust: valores padrão, derive automático, builder pattern e a sintaxe ..Default::default()."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Default Trait em Rust

Guia completo sobre o trait Default em Rust: valores padrão, derive automático, builder pattern e a sintaxe ..Default::default().


## O que é o Default Trait?

O trait `Default` fornece uma maneira padronizada de criar um valor **padrão** para um tipo. Ele responde à pergunta: "Qual é o valor mais razoável e neutro para este tipo?"

Em muitas linguagens, tipos têm valores padrão implícitos (como `0` para inteiros ou `null` para referências). Em Rust, o `Default` trait torna isso **explícito** e **seguro** — sem nulls, sem surpresas.

`Default` é amplamente usado em:
- Inicialização de structs com campos parciais (struct update syntax)
- Builder pattern
- Coleções e containers
- APIs genéricas que precisam de um valor inicial

---

## Definição do Trait

```rust
// Definido em std::default
pub trait Default: Sized {
    fn default() -> Self;
}
```

O trait tem um único método, `default()`, que retorna uma nova instância do tipo com seus valores padrão.

### Valores padrão dos tipos primitivos

| Tipo | Valor padrão |
|------|-------------|
| `bool` | `false` |
| `i8, i16, i32, i64, i128, isize` | `0` |
| `u8, u16, u32, u64, u128, usize` | `0` |
| `f32, f64` | `0.0` |
| `char` | `'\0'` |
| `String` | `""` (string vazia) |
| `Vec<T>` | `vec![]` (vetor vazio) |
| `Option<T>` | `None` |
| `HashMap<K, V>` | mapa vazio |

---

## Como Implementar: derive vs impl manual

### Default com #[derive]

O compilador gera automaticamente uma implementação que chama `Default::default()` para cada campo:

```rust
#[derive(Debug, Default)]
struct ConfigServidor {
    host: String,        // ""
    porta: u16,          // 0
    max_conexoes: usize, // 0
    tls_habilitado: bool, // false
    timeout_ms: Option<u64>, // None
}

fn main() {
    let config = ConfigServidor::default();
    println!("{:#?}", config);
    // ConfigServidor {
    //     host: "",
    //     porta: 0,
    //     max_conexoes: 0,
    //     tls_habilitado: false,
    //     timeout_ms: None,
    // }
}
```

Para usar `#[derive(Default)]`, todos os campos devem implementar `Default`.

### Default com implementação manual

Quando os valores padrão derivados não fazem sentido para o seu domínio:

```rust
#[derive(Debug)]
struct ConfigServidor {
    host: String,
    porta: u16,
    max_conexoes: usize,
    tls_habilitado: bool,
    timeout_ms: Option<u64>,
}

impl Default for ConfigServidor {
    fn default() -> Self {
        ConfigServidor {
            host: String::from("127.0.0.1"),
            porta: 8080,
            max_conexoes: 100,
            tls_habilitado: false,
            timeout_ms: Some(30_000),
        }
    }
}

fn main() {
    let config = ConfigServidor::default();
    println!("{:#?}", config);
    // ConfigServidor {
    //     host: "127.0.0.1",
    //     porta: 8080,
    //     max_conexoes: 100,
    //     tls_habilitado: false,
    //     timeout_ms: Some(30000),
    // }
}
```

### Default para enums

```rust
#[derive(Debug)]
enum NivelLog {
    Erro,
    Aviso,
    Info,
    Debug,
    Trace,
}

impl Default for NivelLog {
    fn default() -> Self {
        NivelLog::Info  // Info é o padrão mais razoável
    }
}

// Com derive, marca a variante padrão com #[default]
#[derive(Debug, Default)]
enum Tema {
    Claro,
    Escuro,
    #[default]
    Sistema, // Segue a preferência do sistema operacional
}

fn main() {
    let nivel = NivelLog::default();
    let tema = Tema::default();
    println!("Nível: {:?}", nivel); // Info
    println!("Tema: {:?}", tema);   // Sistema
}
```

---

## Exemplos Práticos

### Exemplo 1: Struct update syntax com ..Default::default()

A sintaxe `..Default::default()` permite criar uma instância especificando apenas os campos que diferem do padrão:

```rust
#[derive(Debug)]
struct Requisicao {
    metodo: String,
    url: String,
    headers: Vec<(String, String)>,
    corpo: Option<String>,
    timeout_ms: u64,
    seguir_redirect: bool,
    max_redirects: u32,
}

impl Default for Requisicao {
    fn default() -> Self {
        Requisicao {
            metodo: String::from("GET"),
            url: String::new(),
            headers: Vec::new(),
            corpo: None,
            timeout_ms: 30_000,
            seguir_redirect: true,
            max_redirects: 10,
        }
    }
}

fn main() {
    // Especifica apenas url e metodo, o resto é padrão
    let req = Requisicao {
        url: String::from("https://api.exemplo.com/dados"),
        metodo: String::from("POST"),
        corpo: Some(String::from(r#"{"chave": "valor"}"#)),
        ..Default::default()
    };

    println!("{:#?}", req);
    // timeout_ms será 30000
    // seguir_redirect será true
    // max_redirects será 10
}
```

### Exemplo 2: Builder pattern com Default

```rust
#[derive(Debug)]
struct Conexao {
    host: String,
    porta: u16,
    usuario: Option<String>,
    senha: Option<String>,
    pool_tamanho: usize,
    ssl: bool,
}

impl Default for Conexao {
    fn default() -> Self {
        Conexao {
            host: String::from("localhost"),
            porta: 5432,
            usuario: None,
            senha: None,
            pool_tamanho: 10,
            ssl: false,
        }
    }
}

impl Conexao {
    fn builder() -> ConexaoBuilder {
        ConexaoBuilder::default()
    }
}

#[derive(Default)]
struct ConexaoBuilder {
    host: Option<String>,
    porta: Option<u16>,
    usuario: Option<String>,
    senha: Option<String>,
    pool_tamanho: Option<usize>,
    ssl: Option<bool>,
}

impl ConexaoBuilder {
    fn host(mut self, host: impl Into<String>) -> Self {
        self.host = Some(host.into());
        self
    }

    fn porta(mut self, porta: u16) -> Self {
        self.porta = Some(porta);
        self
    }

    fn usuario(mut self, usuario: impl Into<String>) -> Self {
        self.usuario = Some(usuario.into());
        self
    }

    fn ssl(mut self, ssl: bool) -> Self {
        self.ssl = Some(ssl);
        self
    }

    fn build(self) -> Conexao {
        let padrao = Conexao::default();
        Conexao {
            host: self.host.unwrap_or(padrao.host),
            porta: self.porta.unwrap_or(padrao.porta),
            usuario: self.usuario.or(padrao.usuario),
            senha: self.senha.or(padrao.senha),
            pool_tamanho: self.pool_tamanho.unwrap_or(padrao.pool_tamanho),
            ssl: self.ssl.unwrap_or(padrao.ssl),
        }
    }
}

fn main() {
    let conn = Conexao::builder()
        .host("db.exemplo.com")
        .porta(5433)
        .usuario("admin")
        .ssl(true)
        .build();

    println!("{:#?}", conn);
}
```

### Exemplo 3: Default em tipos genéricos

```rust
#[derive(Debug)]
struct Cache<T: Default> {
    dados: Vec<T>,
    capacidade: usize,
}

impl<T: Default> Cache<T> {
    fn novo(capacidade: usize) -> Self {
        Cache {
            dados: Vec::with_capacity(capacidade),
            capacidade,
        }
    }

    fn obter_ou_padrao(&self, indice: usize) -> T {
        if indice < self.dados.len() {
            // Precisaríamos de Clone aqui na prática
            T::default()
        } else {
            T::default()
        }
    }
}

impl<T: Default> Default for Cache<T> {
    fn default() -> Self {
        Cache {
            dados: Vec::new(),
            capacidade: 64,
        }
    }
}

fn main() {
    let cache: Cache<String> = Cache::default();
    println!("Capacidade: {}", cache.capacidade); // 64

    let valor = cache.obter_ou_padrao(999);
    println!("Padrão: '{}'", valor); // ""
}
```

### Exemplo 4: Default com Option e unwrap_or_default

```rust
fn main() {
    // unwrap_or_default usa Default::default() como fallback
    let talvez_numero: Option<i32> = None;
    let numero = talvez_numero.unwrap_or_default();
    println!("{}", numero); // 0

    let talvez_texto: Option<String> = None;
    let texto = talvez_texto.unwrap_or_default();
    println!("'{}'", texto); // ''

    // Útil em iteradores
    let numeros = vec![1, 2, 3];
    let primeiro: i32 = numeros.into_iter().next().unwrap_or_default();
    println!("{}", primeiro); // 1

    let vazio: Vec<i32> = vec![];
    let primeiro: i32 = vazio.into_iter().next().unwrap_or_default();
    println!("{}", primeiro); // 0
}
```

### Exemplo 5: Default para inicializar arrays e coleções

```rust
use std::collections::HashMap;

fn main() {
    // HashMap começa vazio por padrão
    let mut contadores: HashMap<String, usize> = HashMap::default();

    let palavras = vec!["rust", "é", "rust", "incrível", "rust"];

    for palavra in palavras {
        // entry().or_default() usa Default::default() para usize (= 0)
        *contadores.entry(palavra.to_string()).or_default() += 1;
    }

    println!("{:?}", contadores);
    // {"rust": 3, "é": 1, "incrível": 1}

    // Vec de valores padrão
    let zeros: Vec<i32> = std::iter::repeat_with(Default::default)
        .take(5)
        .collect();
    println!("{:?}", zeros); // [0, 0, 0, 0, 0]
}
```

---

## Padrões e Boas Práticas

1. **Use `#[derive(Default)]` quando possível**: Para a maioria dos tipos, os valores padrão gerados automaticamente são adequados. Economize código.

2. **Implemente manualmente quando os defaults importam**: Se porta 0 ou host vazio não fazem sentido para seu tipo, implemente `Default` manualmente com valores significativos.

3. **Combine com struct update syntax**: A construção `{ campo: valor, ..Default::default() }` é um padrão poderoso para APIs com muitas opções.

4. **`or_default()` em vez de `or_insert(0)`**: Em `HashMap`, prefira `entry(k).or_default()` a `entry(k).or_insert(T::default())`. É mais limpo e idiomático.

5. **Default deve ser sensato**: O valor padrão deve ser o mais seguro e neutro possível. Não use defaults que possam causar comportamento inesperado.

6. **`#[default]` em enums**: A partir do Rust 1.62, você pode usar `#[derive(Default)]` em enums marcando a variante padrão com `#[default]`.

7. **Default para builder pattern**: Use `Default` como base para builders. O padrão `..Default::default()` é a alternativa mais simples ao builder pattern para structs com poucos campos.

---

## Veja Também

- [Clone e Copy](/stdlib/clone-copy/) — traits de cópia, frequentemente derivados junto com Default
- [Display e Debug](/stdlib/display-debug/) — outro grupo de traits comumente derivados
- [From e Into](/stdlib/from-into/) — conversões de tipos, complementar a Default para inicialização
- [Eq e Ord](/stdlib/eq-ord/) — traits de comparação, parte do conjunto comum de derives
- [Padrões de Projeto em Rust](/artigos/padroes-projeto-rust/) — builder pattern e outros padrões
