Itération sur une plage avec un pas non standard en Rust : 3 méthodes

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

Comment parcourir des nombres avec un pas de 3, 5 ou 100 en Rust ? Analyse complète



Imaginez : vous codez en Rust et vous devez afficher tous les nombres pairs de 0 à 20. Ou, disons, construire la séquence 0, 5, 10, 15, 20. En Python, vous écririez simplement range(0, 21, 5) — et c'est fait. Qu'en est-il en Rust ? Il y a des nuances, et aujourd'hui nous allons les analyser.



Cette question est l'une des plus populaires sur Stack Overflow (des milliers de vues). Et ce n'est pas surprenant : le standard for i in 0..10 ne fonctionne qu'avec un pas de 1. Mais si vous avez besoin d'un pas différent ? Il s'avère qu'il existe trois méthodes, chacune avec ses avantages et ses pièges.



Nous ne montrerons pas simplement le code — nous comparerons les approches en termes de performances, de lisibilité et de flexibilité. C'est parti !



Pourquoi Rust n'a-t-il pas de plage intégrée avec un pas ?



Réponse courte : parce que Range en Rust est un itérateur simple qui génère une séquence de nombres entiers. Il ne prend pas en charge le pas par défaut afin de rester aussi léger et prévisible que possible. Mais les développeurs ont prévu des méthodes qui résolvent ce problème.



Réponse longue : dans l'écosystème Rust, la philosophie est « l'explicite est meilleur que l'implicite ». Au lieu d'intégrer le pas dans la syntaxe de la plage, les créateurs ont proposé des outils flexibles d'adaptation des itérateurs. Et cela ouvre plus de possibilités qu'il n'y paraît.



Méthode 1 : step_by() — la voie la plus directe



Dans la bibliothèque standard de Rust, il existe la méthode step_by(n) qui crée un itérateur sautant tous les n-1 éléments. Voici comment elle fonctionne :



fn main() {    // Affiche les nombres de 0 à 20 avec un pas de 5    for i in (0..=20).step_by(5) {        println!("{}", i);    }    // Affichage : 0, 5, 10, 15, 20}


Notez que j'ai utilisé 0..=20 (inclusif), et non 0..20 (exclusif). Si vous avez besoin d'un pas de 3 jusqu'à 10, écrivez (0..10).step_by(3) — vous obtiendrez 0, 3, 6, 9.



Avantages de step_by() :

  • Simplicité — une seule ligne, pas de fermetures
  • Lisibilité — on voit immédiatement ce qui est fait
  • Performances — frais généraux minimes


Inconvénients :

  • Fonctionne uniquement avec des nombres entiers (i32, u64, etc.)
  • Impossible de définir un pas dynamique à chaque itération
  • Apparu seulement dans Rust 1.28 (mais c'est déjà ancien)


Cette méthode est le choix idéal pour 90% des tâches. Si vous avez simplement besoin de parcourir des nombres avec un pas constant — utilisez step_by().



Méthode 2 : filter() — quand le pas est une condition



Et si le pas n'est pas constant ? Par exemple, vous devez afficher les nombres qui sont divisibles par 3 sans reste. Ou les nombres dont la somme des chiffres est supérieure à 5. C'est là que filter() vient à la rescousse :



fn main() {    // Tous les nombres de 0 à 30, multiples de 4    for i in (0..=30).filter(|x| x % 4 == 0) {        println!("{}", i);    }    // Affichage : 0, 4, 8, 12, 16, 20, 24, 28

// Et maintenant — les nombres qui ne sont pas divisibles par 3 for i in (0..20).filter(|x| x % 3 != 0) { println!("{}", i); } // Affichage : 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19}


Ici, nous passons une fermeture (closure) qui vérifie chaque nombre. filter() ne conserve que les éléments pour lesquels la condition est vraie.



Quand filter() est meilleur que step_by() :

  • Le pas dépend de la valeur (par exemple, « tous les nombres premiers »)
  • Besoin de combiner avec d'autres conditions
  • Le pas n'est pas constant (par exemple, les nombres de Fibonacci)


Inconvénients :

  • Légèrement plus lent que step_by() — il faut vérifier chaque nombre
  • Le code peut être moins évident pour les débutants


Personnellement, j'utilise filter() quand j'ai besoin non pas simplement de « chaque n-ième », mais de « chacun qui correspond à une règle ». C'est plus puissant, mais demande plus d'attention.

Blogs

Book Recommendations