Formatação de saída

Macros de saída

A funcionalidade de impressão (saída) do Rust é implementada por uma série de macros no módulo std::fmt. Seguem as explicações das macros mais utilizadas:

  • format!:grava o texto formatado em uma string
  • print!:exibe conteúdo no console (saída padrão)
  • println!:igual ao print!, insere quebra de linha automaticamente no final
  • eprint!:exibe conteúdo no fluxo de erro padrão
  • eprintln!:igual ao eprint!, insere quebra de linha automaticamente no final

Todas as macros terminadas com ln adicionam um caractere de quebra de linha, pulando uma linha após a exibição.

O prefixo e significa error, usado para imprimir mensagens de erro

Todas essas macros compartilham a mesma sintaxe de formatação, e o Rust valida se o código de formatação é válido durante a compilação.

Exemplos de uso

Marcador de posição básico {}

{} é um marcador genérico, ele substitui sequencialmente os parâmetros passados depois e converte automaticamente para string para exibição.

fn main() {
    println!("{} days", 31);
    // Saída:31 days
}Code language: JavaScript (javascript)

Parâmetros de posição

Dentro de {}, escreva um índice numérico (começando em 0) para escolher manualmente qual parâmetro usar, suporta reutilização e troca de ordem dos parâmetros.

fn main() {
    println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
    // Saída:Alice, this is Bob. Bob, this is Alice
}Code language: JavaScript (javascript)

No exemplo acima, você vê que os índices dos parâmetros não precisam seguir a sequência 0 1 2…, podem ser embaralhados. Os parâmetros passados “Alice”, “Bob” têm Alice como índice 0 e Bob como índice 1.

Parâmetros nomeados

Se achar o uso por índice pouco intuitivo, pode usar os ” parâmetros nomeados “: dentro da string de formatação use {nome_do_parametro}, na chamada passe valores no formato nome_do_parametro=valor. A ordem não importa e a legibilidade melhora.

fn main() {
    println!("{subject} {verb} {object}",
         object="the lazy dog",
         subject="the quick brown fox",
         verb="jumps over");
    // Saída:the quick brown fox jumps over the lazy dog
}Code language: JavaScript (javascript)

Funciona como se atribuísse um nome aos parâmetros passados, depois na string de formatação você usa {nome_do_parametro} para referenciá-los, muito mais intuitivo.

Formatação de bases numéricas(:especificador

Dentro do marcador de posição, use : seguido de caracteres de formato para converter números para binário, octal, hexadecimal e outras bases.

  • :b:binário
  • :o:octal
  • :x:hexadecimal minúsculo
fn main() {
    println!("Decimal:    {}",   69420);    // 69420
    println!("Binário:  {:b}", 69420);    // 10000111100101100
    println!("Octal:    {:o}", 69420);    // 207454
    println!("Hex:      {:x}", 69420);    // 10f2c
}Code language: JavaScript (javascript)

Largura, alinhamento e preenchimento

1 Alinhamento à direita(>largura

{:>n} define largura total como n, o conteúdo é alinhado à direita com espaços preenchendo a esquerda.

fn main() {
    println!("{number:>5}", number=1);
    // Largura total 5, 4 espaços à esquerda → Saída:    1
}Code language: JavaScript (javascript)
2 Alinhamento com preenchimento de zero

Adicione 0 antes do símbolo de alinhamento para usar o número 0 no lugar de espaços para preenchimento.

  • :0>5:alinhado à direita, preenche com 0 na esquerda
  • :0<5:alinhado à esquerda, preenche com 0 na direita
fn main() {
    println!("{number:0>5}", number=1); // Alinhado direita, preenchimento 0 → 00001
    println!("{number:0<5}", number=1); // Alinhado esquerda, preenchimento 0 → 10000
}Code language: JavaScript (javascript)

Também é possível usar qualquer outro caractere, não apenas 0. O exemplo abaixo preenche a esquerda com a letra maiúscula A

fn main() {
    println!("{number:A>5}", number=1); // Alinhado direita, preenchimento A → AAAA1
    println!("{number:A<5}", number=1); // Alinhado esquerda, preenchimento A → 1AAAA
}Code language: PHP (php)
3 Largura dinâmica(nome_variavel$

A largura não é fixa no código, use nome_variavel$ para referenciar parâmetros nomeados/ variáveis externos e controlar a largura de forma dinâmica.

Ou seja, a largura pode ser controlada por variável, em vez de estar hardcoded no código.

fn main() {
    // Modo 1:combinar com parâmetros nomeados
    println!("{number:0>width$}", number=1, width=8);

    // Modo 2:referenciar variáveis do código diretamente (suportado no Rust 1.58+)
    let number: f64 = 1.0;
    let width: usize = 8;
    println!("{number:>width$}"); // Saída:    1
}Code language: JavaScript (javascript)

Validação de parâmetros na compilação

O Rust verifica durante a compilação se a quantidade de marcadores de posição corresponde ao número de parâmetros passados; faltar parâmetros causa erro de compilação imediato.

fn main() {
    // 2 marcadores, mas apenas 1 parâmetro → falha na compilação
    println!("My name is {0}, {1} {0}", "Bond");
    // Correção:adicionar parâmetro "James"
    println!("My name is {0}, {1} {0}", "Bond", "James");
}Code language: JavaScript (javascript)

Mensagem do compilador: a posição {1} é inválida, pois só foi passado um parâmetro depois.

Erro: referência ao parâmetro posicional 1 inexistente (apenas 1 parâmetro fornecido)
 --> D:\rustdemo\hello.rs:3:29
  |
3 |     println!("My name is {0}, {1} {0}", "Bond");
  |                                ^
  |
  = Dica: parâmetros posicionais são numerados a partir de 0

Erro: compilação interrompida, total de 1 erroCode language: JavaScript (javascript)

Limitações de formatação para tipos personalizados

Por padrão, {} só consegue formatar tipos que implementam o trait fmt::Display. Structs personalizados não vêm com esse trait implementado por padrão; imprimir diretamente com {} gera erro de compilação.

fn main() {
    struct Structure(i32);
    // O código abaixo não compila
    println!("{}", Structure(3));
}Code language: JavaScript (javascript)
Erro[E0277]: a struct `Structure` não implementa o trait `std::fmt::Display`
 --> D:\rustdemo\hello.rs:4:20
4 |     println!("{}", Structure(3));
  |               --   ^^^^^^^^^^^^ esse tipo não pode ser exibido com o formatador padrão
  |               |
  |               esse argumento de formato exige que o tipo implemente o trait Display

Dica: a struct `Structure` não tem implementação de `std::fmt::Display`
 --> D:\rustdemo\hello.rs:2:2
2 |     struct Structure(i32);
  |     ^^^^^^^^^^^^^^^^

Observação: na string de formatação, tente usar `{:?}` (ou `{:#?}` para impressão formatada)
Compilação interrompida, 1 erro encontrado.

Para ver detalhes desse erro, execute o comando: rustc --explain E0277Code language: PHP (php)

* 1 Se precisar imprimir uma struct, é necessário implementar o trait Display (apenas compre por enquanto, veremos depois)

use std::fmt;

struct Structure(i32);

// Implementar trait Display para a struct
impl fmt::Display for Structure {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // self.0 acessa o valor i32 dentro da struct tupla
        write!(f, "Valor:{}", self.0)
    }
}

fn main() {
    println!("{}", Structure(3));
}Code language: PHP (php)
* 2 Depuração temporária → usar formato de depuração {:?} / {:#?}

Ideal para depuração do desenvolvedor: se não for ambiente de produção e só quiser ver os valores internos da struct, use o trait Debug de depuração

O Rust implementa o trait Debug por padrão para tipos personalizados, basta usar {:?} para imprimir:

#[derive(Debug)]
#[allow(dead_code)] // ocultar avisos de código/campo não utilizado
struct Structure(i32);

fn main() {
    println!("{:?}", Structure(3));
    println!("{:#?}", Structure(3));
}Code language: PHP (php)

* Dois traits centrais de formatação do std::fmt

O módulo std::fmt contém vários traits que controlam a exibição de texto, os dois principais são:

  1. fmt::Debug usado com o marcador {:?}, exclusivo para exibição em cenários de depuração.
  2. fmt::Display usado com o marcador {}, mostra conteúdo de forma padronizada e amigável para usuários finais.

Tipos nativos da biblioteca padrão já têm esses dois traits implementados por padrão e podem ser impressos diretamente; tipos personalizados não funcionam sem implementação manual.

Ao implementar fmt::Display em um tipo, o trait ToString é implementado automaticamente, permitindo converter o tipo para string.

#[allow(dead_code)]

#[allow(dead_code)] é um atributo de código aplicado ao item de código seguinte, serve para ocultar avisos de “código não utilizado”.

No exemplo acima

fn main() {
    struct Structure(i32);
    // O código abaixo não compila
    //println!("{}", Structure(3));
}Code language: JavaScript (javascript)

A linha println!(“{}”, Structure(3)); causa erro e está comentada. Se executar assim,

Aviso: a struct `Structure` nunca é instanciada
 --> D:\rustdemo\hello.rs:2:12
  |
2 |     struct Structure(i32);
  |            ^^^^^^^^^
  |
  = nota: `#&#91;warn(dead_code)]` (parte de `#&#91;warn(unused)]`) ativado por padrão

1 aviso emitido
Code language: JavaScript (javascript)

Esse aviso aparece pois a linha struct Structure(i32); nunca é usada. Para ocultar esse aviso, adicione esse atributo

fn main() {
    #[allow(dead_code)] 
    struct Structure(i32);
    // O código abaixo não compila
    //println!("{}", Structure(3));
}Code language: PHP (php)
Para números de ponto flutuante: definir casas decimais

Crie uma variável pi = 3.141592, escreva um código de formatação que mantenha três casas decimais, saída esperada:Pi is roughly 3.142.

fn main() {
    let pi = 3.141592;
    println!("Pi is roughly {:.3}", pi);//3.142
    println!("Pi is roughly {0}", pi); //3.141592
}Code language: JavaScript (javascript)

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *