Introduction : les vecteurs, c'est simple, jusqu'à ce qu'il faille les assembler
\nImaginez : vous écrivez un programme en Rust qui traite des données. Vous obtenez deux Vec<i32> et vous voulez les fusionner en un seul. Cela semble simple, non ? Mais tous ceux qui ont posé cette question sur Stack Overflow (et ils sont des milliers !) le savent : en Rust, il existe au moins 5 façons de le faire, et la moitié d'entre elles sont des erreurs qui soit ne compileront pas, soit dévoreront toutes les performances.
Dans cet article, nous allons décortiquer la question populaire « What is the best way to concatenate vectors in Rust? » et la transformer en guide pratique. Vous apprendrez comment fusionner des vecteurs correctement, quels pièges attendent les débutants et comment écrire du code efficace en Rust. C'est parti !
\n\nPourquoi la concaténation de vecteurs en Rust n'est-elle pas une tâche si triviale ?
\nContrairement à Python ou JavaScript, où l'on peut simplement écrire list1 + list2, Rust exige de préciser explicitement ce que l'on veut faire avec la mémoire. Un vecteur en Rust n'est pas simplement une liste, mais une structure qui possède des données sur le tas. Les opérations sur celui-ci peuvent entraîner :
- \n
- Des réallocations (copie de l'intégralité du tampon). \n
- Une perte de possession (sémantique de déplacement). \n
- Des clonages inutiles (si les données sont volumineuses). \n
Par conséquent, le choix de la méthode dépend du contexte : avez-vous besoin de conserver les vecteurs d'origine, quel type de données contiennent-ils, la vitesse est-elle importante.
\n\nTop 5 des erreurs lors de la fusion de vecteurs en Rust
\nPassons en revue les râteaux les plus courants sur lesquels les débutants (et pas seulement) marchent.
\n\nErreur n°1 : Utiliser + pour Vec (ne compilera pas)
\nLa tentative la plus intuitive, mais incorrecte :
\nlet v1 = vec![1, 2, 3];\nlet v2 = vec![4, 5, 6];\nlet v3 = v1 + v2; // Erreur ! cannot add `Vec<{integer}>` to `Vec<{integer}>`\nL'opérateur + n'est surchargé que pour les chaînes et les nombres, mais pas pour les vecteurs. Rust ne permet pas d'additionner des collections « à la volée ».
Erreur n°2 : Oublier le déplacement et perdre des données
\nBeaucoup utilisent append et sont surpris que le premier vecteur se vide :
let mut v1 = vec![1, 2, 3];\nlet mut v2 = vec![4, 5, 6];\nv1.append(&mut v2);\nprintln!("{:?}", v2); // Vide ! v2 est maintenant vide.\nappend déplace les éléments du deuxième vecteur vers le premier, laissant v2 vide. C'est efficace, mais pas toujours attendu.
Erreur n°3 : Clonage naïf de tout et n'importe quoi
\nLorsqu'il faut conserver les deux vecteurs d'origine, les débutants écrivent souvent :
\nlet v1 = vec![1, 2, 3];\nlet v2 = vec![4, 5, 6];\nlet mut v3 = v1.clone();\nv3.extend(v2.clone()); // Deux clonages !\nPour les grands vecteurs avec des String ou des structures complexes, cela tue les performances. Il est préférable d'utiliser des références ou chain.
Erreur n°4 : Ignorer la capacity lors de extend
\nUn simple extend peut provoquer de multiples réallocations :
let mut v1 = vec![1, 2, 3];\nlet v2 = vec![4, 5, 6];\nv1.extend(v2); // Si la capacité de v1 est petite, il y aura une réallocation.\nSi vous connaissez la taille finale, il est préférable d'allouer la mémoire à l'avance : v1.reserve(v2.len()).
Erreur n°5 : Confusion entre extend et append
\nextend accepte un itérateur et peut cloner des éléments (si on passe &vec). append déplace les éléments sans clonage. Le choix n'est pas évident tant qu'on n'a pas lu la documentation.
Les meilleures façons de fusionner des vecteurs en Rust (avec exemples)
\nMaintenant que nous connaissons l'ennemi, examinons les approches correctes. Chacune est adaptée à son scénario.
\n\nMéthode 1 : extend — universel et compréhensible
\nLa méthode la plus courante. Ajoute des éléments