Itération sur Vec avec index en Rust : 4 façons de comparer

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Itération sur Vec avec index en Rust : du débutant au pro



Imaginez : vous codez en Rust et devez parcourir les éléments d'un vecteur, tout en connaissant non seulement la valeur, mais aussi sa position. Une tâche simple en apparence, mais qui laisse souvent les débutants perplexes. Où est le for i in range(len(vec)), comme en Python ? Et si je veux modifier les éléments ? Qu'est-ce qui est le plus rapide ?



Dans cet article, nous allons détailler toutes les méthodes populaires d'itération sur Vec avec index en Rust, comparer leurs performances, leur lisibilité et leur sécurité. Vous découvrirez quelle méthode choisir en 2024 et pourquoi enumerate n'est pas toujours une solution miracle.



Pourquoi est-ce important ?

En Rust, il n'y a pas de for i in 0..vec.len() comme seule voie correcte. Le langage propose plusieurs paradigmes : des itérateurs fonctionnels aux boucles de bas niveau. Comprendre la différence entre eux est la clé pour écrire un code efficace et idiomatique. C'est particulièrement crucial lorsqu'on travaille avec des vecteurs, où l'index peut être nécessaire pour modifier des éléments voisins ou suivre une position dans un algorithme.



Méthode 1 : La classique — enumerate

La méthode la plus courante et recommandée. La méthode enumerate enveloppe l'itérateur, en ajoutant son index à chaque élément :



let vec = vec!["a", "b", "c", "d"];for (index, value) in vec.iter().enumerate() {    println!("Position {} : {}", index, value);}


Avantages :

  • Idiomatique et lisible
  • Sûr — aucun risque de dépassement de limites
  • Fonctionne avec n'importe quel itérateur, pas seulement Vec

Inconvénients : Impossible de modifier directement les éléments du vecteur (nécessite iter_mut()).



Méthode 2 : Par index — 0..vec.len()

Une approche familière à tous ceux venant du C++ ou Python. On utilise une plage d'index :



let mut vec = vec![10, 20, 30, 40];for i in 0..vec.len() {    vec[i] += i; // modifie l'élément à l'index    println!("vec[{}] = {}", i, vec[i]);}


Avantages :

  • Contrôle total sur l'index et l'élément
  • Possibilité de modifier les éléments via vec[i]
  • Intuitif pour les débutants

Inconvénients : Plus lent que les itérateurs (vérification supplémentaire des limites). La communauté Rust le considère comme "non idiomatique".



Méthode 3 : while avec compteur

La méthode la plus "manuelle", que l'on rencontre dans du code ancien ou lors d'optimisations :



let vec = vec![1.0, 2.0, 3.0];let mut i = 0;while i < vec.len() {    println!("Élément {} : {}", i, vec[i]);    i += 1;}


Avantages : Flexibilité maximale (possibilité de sauter des index, de modifier le pas).

Inconvénients : Facile de se tromper dans la condition. Déconseillé sans raison valable.



Méthode 4 : zip avec une plage

Une approche fonctionnelle, utile lorsqu'il faut itérer deux vecteurs en parallèle avec des index :



let names = vec!["Alice", "Bob", "Charlie"];let scores = vec![95, 87, 92];

for (i, (name, score)) in (0..).zip(names.iter()).zip(scores.iter()) { println!("{} : {} a obtenu {} points", i, name, score);}


Avantages : Puissant pour l'itération parallèle. La plage infinie 0.. est automatiquement tronquée.

Inconvénients : Peut être difficile à lire. Excessif pour des tâches simples.



Comparaison des performances

Nous avons effectué des benchmarks sur un vecteur de 100 000 éléments (optimisation --release) :



Blogs

Book Recommendations

MéthodeTemps (ns)Vitesse relative
enumerate~12 0001.0x (référence)
0..len~15 0001.25x plus lent