« Comment afficher un Vec ? » — la question que tout développeur Rust s'est posée
\n\nSi vous avez déjà écrit du code en Rust et essayé d'afficher simplement un vecteur à l'écran, vous avez sûrement rencontré ceci :
\n\nfn main() {\n let numbers = vec![1, 2, 3, 4, 5];\n println!("{}", numbers); // Erreur !\n}\n\nLe compilateur vous accueille avec un message rouge : `Vec<{integer}>` doesn't implement `std::fmt::Display`. Familier ? Cette question sur Stack Overflow a recueilli des milliers de vues, et pour cause. En Rust, il n'y a pas de « magie » — le compilateur exige que vous spécifiiez comment vous souhaitez afficher la collection. Et c'est une bonne chose, car cela vous donne un contrôle total.
Dans cet article, nous allons passer en revue toutes les principales méthodes pour afficher un Vec en Rust : de l'affichage de débogage rapide à la création d'un formatage élégant pour l'utilisateur. Vous apprendrez quelle méthode utiliser selon le contexte, et vous cesserez de craindre les erreurs de compilation.
\n\nPourquoi Vec n'implémente-t-il pas Display ?
\n\nAvant de plonger dans le code, comprenons la philosophie de Rust. Le trait Display est destiné à afficher des données à l'utilisateur — comme vous souhaitez les voir dans une interface. Tandis que Debug est destiné au débogage et aux logs.
Pour un vecteur, il est impossible de deviner le format dont vous avez besoin :
\n- \n
- Afficher les éléments séparés par des virgules ? \n
- Chaque élément sur une nouvelle ligne ? \n
- Entre crochets, comme un tableau ? \n
- Ou sous forme de tableau ? \n
C'est pourquoi les développeurs de Rust ont décidé de ne pas imposer un format unique, mais de laisser le choix au programmeur. Voyons quelles options s'offrent à nous.
\n\nMéthode 1 : Affichage de débogage rapide (Debug)
\n\nLa méthode la plus simple consiste à utiliser {:?} ou {:#?} (pretty-print). Pour cela, le type des éléments du vecteur doit implémenter le trait Debug.
fn main() {\n let numbers = vec![1, 2, 3, 4, 5];\n println!("{:?}", numbers); // [1, 2, 3, 4, 5]\n println!("{:#?}", numbers); // Affichage élégant :\n // [\n // 1,\n // 2,\n // 3,\n // 4,\n // 5\n // ]\n}\n\nQuand l'utiliser : débogage, journalisation, vérification rapide. Généralement inadapté pour la production — le format n'est pas flexible.
\n\nImportant : si votre type n'implémente pas Debug, le compilateur vous le signalera. Pour vos propres structures, vous pouvez ajouter #[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\nMéthode 2 : Parcours manuel avec un itérateur
\n\nLa méthode la plus flexible consiste à écrire votre propre boucle. Vous obtenez un contrôle total sur le format.
\n\nfn main() {\n let words = vec!["hello", "world", "rust"];\n \n // Variante 1 : séparés par des virgules\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 // Variante 2 : chacun sur une nouvelle ligne\n for word in &words {\n println!("- {}", word);\n }\n // - hello\n // - world\n // - rust\n}\n\nCette approche offre une flexibilité maximale, mais nécessite plus de code. Idéale lorsqu'un formatage unique est requis.
\n\nMéthode 3 : Utilisation d'un itérateur avec collect et join
\n\nSi vous avez simplement besoin de joindre les éléments en une chaîne, vous pouvez utiliser join du trait SliceConcatExt (disponible pour les slices) :
fn main() {\n let words = vec!["hello", "world", "rust"];\n let joined = words.join(", ");\n println!("{}", joined); //