Boucle for inversée en Rust : comment éviter les pièges du débutant

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

Introduction : pourquoi la boucle for inversée en Rust est-elle un piège pour les débutants ?

\n\n

Imaginez la situation : vous passez de Python à Rust. Tout semble clair, mais lorsque vous devez parcourir un tableau dans l'ordre inverse, vous écrivez for i in 0..10 et vous découvrez avec surprise que Rust ne va que vers l'avant. Vous essayez d'écrire for i in 10..0 — et vous obtenez une boucle vide. Cela vous semble familier ? Si oui, vous n'êtes pas seul. La question « How to make a reverse ordered for loop » sur Stack Overflow a recueilli des milliers de vues, et ce n'est pas surprenant.

\n\n

Dans cet article, nous allons analyser les principales erreurs que commettent les débutants lorsqu'ils travaillent avec des boucles inversées en Rust, et montrer comment les éviter. Vous apprendrez pourquoi 10..0 ne fonctionne pas, comment utiliser la méthode .rev() et les itérateurs, ainsi que comment ne pas casser votre code lorsque vous travaillez avec des vecteurs et des tranches. C'est parti !

\n\n

Erreur n°1 : Utilisation naïve d'une plage dans le sens inverse

\n\n

L'erreur la plus courante est d'essayer d'écrire for i in 10..0 en espérant que Rust comprenne : « ah, l'utilisateur veut aller dans l'ordre inverse ». Hélas, en Rust, la plage a..b va toujours de a à b non inclus. Si a >= b, alors la plage est vide.

\n\n
// ❌ Erreur : boucle vide\nfor i in 10..0 {\n    println!("{}", i); // Rien ne s'affichera\n}
\n\n

Pourquoi cela ? Rust est un langage strict. Les plages ne savent pas s'inverser automatiquement. Cela a été fait pour des raisons de performance et de prévisibilité. Si 10..0 fonctionnait comme une plage inversée, le compilateur devrait vérifier chaque nombre pour savoir « est-ce que la valeur de départ est supérieure à la valeur de fin ? », ce qui ralentirait les boucles normales.

\n\n

Comment corriger : utilisez la méthode .rev()

\n\n

La bonne façon est de créer une plage croissante normale, puis d'appeler la méthode .rev() qui inverse l'itérateur :

\n\n
// ✅ Correct : on utilise .rev()\nfor i in (0..10).rev() {\n    println!("{}", i); // Affichera : 9, 8, 7, ..., 0\n}
\n\n

Notez bien : nous utilisons (0..10).rev(), et non 10..0. Les parenthèses sont obligatoires, car 0..10.rev() appellerait la méthode sur 10, et non sur la plage. C'est une autre erreur fréquente.

\n\n

Erreur n°2 : Oubli des parenthèses autour de la plage

\n\n

La méthode .rev() est appelée sur un itérateur. La plage 0..10 est un itérateur. Mais si vous écrivez 0..10.rev(), Rust interprète cela comme 0..(10.rev()), et le nombre entier 10 n'a pas de méthode rev(). Le compilateur générera une erreur :

\n\n
// ❌ Erreur de compilation : un nombre n'a pas de méthode rev()\nfor i in 0..10.rev() {\n    // error[E0599]: no method named `rev` found for integer `i32`\n}
\n\n

La solution est simple — utilisez des parenthèses :

\n\n
// ✅ Les parenthèses résolvent tout\nfor i in (0..10).rev() {\n    println!("{}", i);\n}
\n\n

Erreur n°3 : Tentative d'inverser un non-itérateur

\n\n

Parfois, les débutants essaient d'appliquer .rev() directement à un vecteur ou un tableau :

\n\n
let numbers = vec![1, 2, 3, 4, 5];\n\n// ❌ Erreur : Vec n'a pas de méthode rev()\nfor i in numbers.rev() {\n    println!("{}", i);\n}
\n\n

.rev() est une méthode d'itérateur, pas de collection. Pour inverser un vecteur, vous devez d'abord obtenir un itérateur avec .iter() ou .into_iter(), puis appeler .rev() :

\n\n
let numbers = vec![1, 2, 3, 4, 5];\n\n// ✅ Correct : on obtient un itérateur, puis on inverse\nfor i in numbers.iter().rev() {\n    println!("{}", i); // Affichera : 5, 4, 3, 2, 1\n}
\n\n

Si vous devez posséder les éléments (par exemple, pour les déplacer), utilisez .into_iter().rev() :

\n\n
let numbers = vec![1, 2, 3, 4, 5];\n\nfor i in numbers.into_iter().rev() {\n    println!("{}", i); // numbers est maintenant                

Blogs

Book Recommendations