Imprimindo Vec em Rust: do iniciante ao profissional

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

«Como imprimir Vec?» — a pergunta que todo desenvolvedor Rust já fez

\n\n

Se você já programou em Rust e tentou simplesmente imprimir um vetor na tela, certamente já se deparou com isto:

\n\n
fn main() {\n    let numbers = vec![1, 2, 3, 4, 5];\n    println!("{}", numbers); // Erro!\n}
\n\n

O compilador recebe você com uma mensagem vermelha: `Vec<{integer}>` doesn't implement `std::fmt::Display`. Familiar? Esta pergunta no Stack Overflow acumulou milhares de visualizações, e não é à toa. Em Rust não existe «mágica» — o compilador exige que você especifique como exatamente deseja exibir a coleção. E isso é ótimo, porque dá controle total.

\n\n

Neste artigo, abordaremos todas as principais formas de imprimir Vec em Rust: desde a saída de depuração rápida até a criação de formatação bonita para o usuário. Você aprenderá qual método usar quando e deixará de temer os erros de compilação.

\n\n

Por que Vec não implementa Display?

\n\n

Antes de mergulharmos no código, vamos entender a filosofia do Rust. A trait Display é destinada a exibir dados para o usuário — da forma como você deseja vê-los na interface. Já Debug é para depuração e logs.

\n\n

Para um vetor, é impossível adivinhar qual formato você precisa:

\n
    \n
  • Exibir elementos separados por vírgula?
  • \n
  • Cada elemento em uma nova linha?
  • \n
  • Entre colchetes, como um array?
  • \n
  • Ou em formato de tabela?
  • \n
\n\n

Por isso, os desenvolvedores do Rust decidiram não impor um formato único, mas deixar a escolha para o programador. Vamos ver quais opções temos.

\n\n

Forma 1: Saída de depuração rápida (Debug)

\n\n

A forma mais simples é usar {:?} ou {:#?} (pretty-print). Para isso, o tipo dos elementos do vetor deve implementar a trait Debug.

\n\n
fn main() {\n    let numbers = vec![1, 2, 3, 4, 5];\n    println!("{:?}", numbers);    // [1, 2, 3, 4, 5]\n    println!("{:#?}", numbers);   // Saída bonita:\n                                  // [\n                                  //     1,\n                                  //     2,\n                                  //     3,\n                                  //     4,\n                                  //     5\n                                  // ]\n}
\n\n

Quando usar: depuração, registro de logs, verificação rápida. Geralmente não é adequado para produção — o formato não é flexível.

\n\n

Importante: se seu tipo não implementa Debug, o compilador avisará. Para suas próprias estruturas, você pode adicionar #[derive(Debug)]:

\n\n
#[derive(Debug)]\nstruct Point {\n    x: f64,\n    y: f64,\n}\n\nfn main() {\n    let points = vec![Point { x: 1.0, y: 2.0 }, Point { x: 3.0, y: 4.0 }];\n    println!("{:?}", points);\n}
\n\n

Forma 2: Iteração manual com iterador

\n\n

A forma mais flexível é escrever seu próprio loop. Você obtém controle total sobre o formato.

\n\n
fn main() {\n    let words = vec!["hello", "world", "rust"];\n    \n    // Opção 1: separados por vírgula\n    for (i, word) in words.iter().enumerate() {\n        if i > 0 {\n            print!(", ");\n        }\n        print!("{}", word);\n    }\n    println!(); // hello, world, rust\n\n    // Opção 2: cada um em uma nova linha\n    for word in &words {\n        println!("- {}", word);\n    }\n    // - hello\n    // - world\n    // - rust\n}
\n\n

Esta abordagem oferece máxima flexibilidade, mas requer mais código. É ideal quando você precisa de formatação única.

\n\n

Forma 3: Uso de iterador com collect e join

\n\n

Se você precisa apenas juntar os elementos em uma string, pode usar join da trait SliceConcatExt (disponível para slices):

\n\n
fn main() {\n    let words = vec!["hello", "world", "rust"];\n    let joined = words.join(", ");\n    println!("{}", joined); //                

Blogs

Book Recommendations