---
title: "Modulo std::fmt em Rust: Formatacao Completa"
url: "https://rustlang.com.br/stdlib/fmt-module/"
markdown_url: "https://rustlang.com.br/stdlib/fmt-module.MD"
description: "Guia completo do modulo std::fmt em Rust: format!, write!, Display, Debug, Formatter, padding, alinhamento, precisao e formatacao customizada."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Modulo std::fmt em Rust: Formatacao Completa

Guia completo do modulo std::fmt em Rust: format!, write!, Display, Debug, Formatter, padding, alinhamento, precisao e formatacao customizada.


## Visao Geral do Modulo std::fmt

O modulo `std::fmt` e o coracao do sistema de formatacao do Rust. Ele define as traits e tipos que tornam possivel transformar qualquer valor em texto. Cada vez que voce usa `println!`, `format!`, `write!` ou `eprintln!`, o modulo `std::fmt` esta trabalhando por tras.

Os dois pilares do sistema sao as traits `Display` e `Debug`:
- **`Display`** — formatacao voltada ao usuario final (ativada por `{}`)
- **`Debug`** — formatacao voltada ao desenvolvedor (ativada por `{:?}`)

Alem dessas, o modulo oferece controle fino sobre alinhamento, preenchimento, precisao, base numerica e muito mais. Entender `std::fmt` permite criar saidas formatadas elegantes sem depender de crates externas.

---

## Traits e Tipos Principais

### Traits de Formatacao

| Trait | Placeholder | Descricao |
|---|---|---|
| `Display` | `{}` | Formatacao para usuario final |
| `Debug` | `{:?}` | Formatacao para debug |
| `Binary` | `{:b}` | Formato binario |
| `Octal` | `{:o}` | Formato octal |
| `LowerHex` | `{:x}` | Hexadecimal minusculo |
| `UpperHex` | `{:X}` | Hexadecimal maiusculo |
| `LowerExp` | `{:e}` | Notacao cientifica minuscula |
| `UpperExp` | `{:E}` | Notacao cientifica maiuscula |
| `Pointer` | `{:p}` | Endereco de memoria |

### Tipos do Modulo

| Tipo | Descricao |
|---|---|
| `Formatter` | Controla como a saida e escrita |
| `Arguments` | Argumentos pre-compilados para formatacao |
| `Error` | Erro retornado por operacoes de formatacao |
| `Result` | Alias para `Result<(), fmt::Error>` |

### Macros Relacionadas

| Macro | Descricao |
|---|---|
| `format!()` | Retorna uma `String` formatada |
| `print!()`/`println!()` | Escreve em stdout |
| `eprint!()`/`eprintln!()` | Escreve em stderr |
| `write!()`/`writeln!()` | Escreve em qualquer `Write` |

---

## Exemplos Praticos

### 1. Sintaxe de Formatacao Completa

```rust
fn main() {
    let nome = "Rust";
    let versao = 1.75;
    let contagem = 42;

    // Formatacao posicional
    println!("{0} tem versao {1}, e {0} e incrivel!", nome, versao);

    // Formatacao nomeada
    println!("{linguagem} v{ver}", linguagem = nome, ver = versao);

    // Captura de variavel (Rust 1.58+)
    println!("{nome} v{versao}");

    // Padding e alinhamento
    println!("[{:>20}]", nome);    // alinhado a direita:  [                Rust]
    println!("[{:<20}]", nome);    // alinhado a esquerda: [Rust                ]
    println!("[{:^20}]", nome);    // centralizado:        [        Rust        ]
    println!("[{:*^20}]", nome);   // com preenchimento:   [********Rust********]

    // Largura minima e precisao
    println!("{:.2}", 3.14159);     // 3.14
    println!("{:10.2}", 3.14159);   // "      3.14"
    println!("{:010.2}", 3.14159);  // "0000003.14"

    // Bases numericas
    println!("Decimal: {contagem}");
    println!("Binario: {contagem:b}");
    println!("Octal: {contagem:o}");
    println!("Hex minusculo: {contagem:x}");
    println!("Hex maiusculo: {contagem:X}");
    println!("Com prefixo: {contagem:#b}, {contagem:#o}, {contagem:#x}");

    // Sinal explicito
    println!("{:+}", 42);   // +42
    println!("{:+}", -42);  // -42

    // Notacao cientifica
    println!("{:e}", 1000.0);   // 1e3
    println!("{:E}", 0.001);    // 1E-3
}
```

### 2. Implementando Display e Debug

```rust
use std::fmt;

#[derive(Debug)] // Debug pode ser derivado automaticamente
struct Cor {
    r: u8,
    g: u8,
    b: u8,
}

// Display precisa ser implementado manualmente
impl fmt::Display for Cor {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "#{:02X}{:02X}{:02X}", self.r, self.g, self.b)
    }
}

struct Matriz {
    linhas: Vec<Vec<f64>>,
}

impl fmt::Display for Matriz {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for (i, linha) in self.linhas.iter().enumerate() {
            if i > 0 {
                writeln!(f)?;
            }
            write!(f, "| ")?;
            for (j, val) in linha.iter().enumerate() {
                if j > 0 {
                    write!(f, "  ")?;
                }
                write!(f, "{val:8.2}")?;
            }
            write!(f, " |")?;
        }
        Ok(())
    }
}

fn main() {
    let vermelho = Cor { r: 255, g: 0, b: 0 };
    println!("Display: {vermelho}");   // #FF0000
    println!("Debug: {vermelho:?}");   // Cor { r: 255, g: 0, b: 0 }

    let m = Matriz {
        linhas: vec![
            vec![1.0, 2.5, 3.0],
            vec![4.0, 5.123, 6.0],
        ],
    };
    println!("{m}");
    // |     1.00     2.50     3.00 |
    // |     4.00     5.12     6.00 |
}
```

### 3. Formatacao Customizada com Formatter

```rust
use std::fmt;

struct Bytes(u64);

impl fmt::Display for Bytes {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let valor = self.0;
        let (num, unidade) = if valor >= 1_073_741_824 {
            (valor as f64 / 1_073_741_824.0, "GiB")
        } else if valor >= 1_048_576 {
            (valor as f64 / 1_048_576.0, "MiB")
        } else if valor >= 1024 {
            (valor as f64 / 1024.0, "KiB")
        } else {
            return write!(f, "{valor} B");
        };

        // Respeita a precisao definida pelo usuario
        if let Some(precisao) = f.precision() {
            write!(f, "{num:.precisao$} {unidade}")
        } else {
            write!(f, "{num:.2} {unidade}")
        }
    }
}

fn main() {
    let tamanho = Bytes(1_500_000);
    println!("{tamanho}");       // 1.43 MiB
    println!("{tamanho:.4}");    // 1.4305 MiB
    println!("{}", Bytes(500));  // 500 B
    println!("{}", Bytes(2_147_483_648)); // 2.00 GiB
}
```

### 4. Usando write! com Buffers

```rust
use std::fmt::Write;

fn gerar_tabela(dados: &[(&str, f64)]) -> String {
    let mut saida = String::new();

    writeln!(saida, "+{:-<20}+{:-<12}+", "", "").unwrap();
    writeln!(saida, "| {:18} | {:>10} |", "Item", "Preco (R$)").unwrap();
    writeln!(saida, "+{:-<20}+{:-<12}+", "", "").unwrap();

    let mut total = 0.0;
    for (item, preco) in dados {
        writeln!(saida, "| {:18} | {:>10.2} |", item, preco).unwrap();
        total += preco;
    }

    writeln!(saida, "+{:-<20}+{:-<12}+", "", "").unwrap();
    writeln!(saida, "| {:18} | {:>10.2} |", "TOTAL", total).unwrap();
    writeln!(saida, "+{:-<20}+{:-<12}+", "", "").unwrap();

    saida
}

fn main() {
    let itens = vec![
        ("Teclado mecanico", 450.00),
        ("Mouse gamer", 200.50),
        ("Monitor 27\"", 1899.99),
    ];

    print!("{}", gerar_tabela(&itens));
}
```

### 5. Debug Customizado e Pretty-Print

```rust
use std::fmt;

struct Config {
    host: String,
    porta: u16,
    senha: String,
    max_conexoes: usize,
}

impl fmt::Debug for Config {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Config")
            .field("host", &self.host)
            .field("porta", &self.porta)
            .field("senha", &"***") // Oculta a senha
            .field("max_conexoes", &self.max_conexoes)
            .finish()
    }
}

impl fmt::Display for Config {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{} (max: {} conexoes)", self.host, self.porta, self.max_conexoes)
    }
}

fn main() {
    let cfg = Config {
        host: "localhost".into(),
        porta: 5432,
        senha: "super_secreta_123".into(),
        max_conexoes: 100,
    };

    // Display: para o usuario
    println!("{cfg}");
    // localhost:5432 (max: 100 conexoes)

    // Debug compacto
    println!("{cfg:?}");
    // Config { host: "localhost", porta: 5432, senha: "***", max_conexoes: 100 }

    // Debug pretty-print
    println!("{cfg:#?}");
    // Config {
    //     host: "localhost",
    //     porta: 5432,
    //     senha: "***",
    //     max_conexoes: 100,
    // }
}
```

---

## Padroes Comuns

### Especificadores de Formato — Referencia Rapida

A sintaxe completa de um placeholder e:

```
{[argumento][:[preenchimento][alinhamento][sinal][#][0][largura][.precisao][tipo]]}
```

Onde:
- **preenchimento** — qualquer caractere (padrao: espaco)
- **alinhamento** — `<` (esquerda), `>` (direita), `^` (centro)
- **sinal** — `+` para sempre mostrar o sinal
- **#** — forma alternativa (`#b` = `0b`, `#x` = `0x`, `#?` = pretty-print)
- **0** — preenche com zeros
- **largura** — largura minima do campo
- **precisao** — casas decimais ou tamanho maximo de string
- **tipo** — `b`, `o`, `x`, `X`, `e`, `E`, `?`, `p`

### Largura e Precisao Dinamicas

Voce pode usar argumentos para definir largura e precisao em tempo de execucao:

```rust
fn main() {
    let largura = 20;
    let precisao = 3;
    println!("{:>largura$.precisao$}", 3.14159);
    // "               3.142"

    // Usando posicao
    println!("{0:>1$.2$}", 3.14159, 20, 3);
}
```

### Implementando Display para Enums

```rust
use std::fmt;

enum Status {
    Ativo,
    Inativo,
    Pendente(String),
}

impl fmt::Display for Status {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Status::Ativo => write!(f, "Ativo"),
            Status::Inativo => write!(f, "Inativo"),
            Status::Pendente(motivo) => write!(f, "Pendente: {motivo}"),
        }
    }
}
```

---

## Quando Usar (e Quando Nao Usar)

**Use `std::fmt` quando:**
- Precisar de formatacao customizada para seus tipos
- Quiser controlar a representacao textual de structs e enums
- Precisar gerar saida tabulada ou alinhada
- Quiser ocultar campos sensiveis no `Debug`

**Nao use `std::fmt` quando:**
- Precisar de serializacao completa (JSON, TOML) — use `serde`
- Precisar de templates HTML — use crates como `askama` ou `tera`
- Precisar de formatacao de datas/horas complexa — use `chrono`

**Dica:** Sempre implemente `Display` para tipos que serao exibidos ao usuario. Derive `Debug` para todos os tipos durante o desenvolvimento. Use `#[derive(Debug)]` liberalmente — o custo e zero quando nao usado.

---

## Veja Tambem

- [Formatar Strings em Rust](/receitas/formatar-strings/) — receitas praticas de formatacao
- [Display e Debug](/stdlib/display-debug/) — aprofundamento nas traits de exibicao
- [String e &str](/stdlib/string/) — tipos de texto que implementam `Display`
- [O Prelude do Rust](/stdlib/prelude/) — traits de formatacao importadas automaticamente
- [Documentacao oficial — std::fmt](https://doc.rust-lang.org/std/fmt/index.html)
