«Como imprimir Vec?» — a pergunta que todo desenvolvedor Rust já fez
\n\nSe você já programou em Rust e tentou simplesmente imprimir um vetor na tela, certamente já se deparou com isto:
\n\nfn main() {\n let numbers = vec![1, 2, 3, 4, 5];\n println!("{}", numbers); // Erro!\n}\n\nO 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.
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\nPor que Vec não implementa Display?
\n\nAntes 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.
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
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\nForma 1: Saída de depuração rápida (Debug)
\n\nA forma mais simples é usar {:?} ou {:#?} (pretty-print). Para isso, o tipo dos elementos do vetor deve implementar a trait Debug.
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\nQuando usar: depuração, registro de logs, verificação rápida. Geralmente não é adequado para produção — o formato não é flexível.
\n\nImportante: se seu tipo não implementa Debug, o compilador avisará. Para suas próprias estruturas, você pode adicionar #[derive(Debug)]:
#[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\nForma 2: Iteração manual com iterador
\n\nA forma mais flexível é escrever seu próprio loop. Você obtém controle total sobre o formato.
\n\nfn 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\nEsta abordagem oferece máxima flexibilidade, mas requer mais código. É ideal quando você precisa de formatação única.
\n\nForma 3: Uso de iterador com collect e join
\n\nSe você precisa apenas juntar os elementos em uma string, pode usar join da trait SliceConcatExt (disponível para slices):
fn main() {\n let words = vec!["hello", "world", "rust"];\n let joined = words.join(", ");\n println!("{}", joined); //