Introducción: ¿Por qué el bucle for inverso en Rust es una trampa para principiantes?
\n\nImagina la situación: pasas de Python a Rust. Todo parece claro, pero cuando necesitas recorrer un array en orden inverso, escribes for i in 0..10 y descubres con sorpresa que Rust solo avanza. Intentas escribir for i in 10..0 y obtienes un bucle vacío. ¿Te suena? Si es así, no estás solo. La pregunta «How to make a reverse ordered for loop» en Stack Overflow ha acumulado miles de visitas, y no es de extrañar.
En este artículo, analizaremos los principales errores que cometen los principiantes al trabajar con bucles inversos en Rust y mostraremos cómo evitarlos. Aprenderás por qué 10..0 no funciona, cómo usar el método .rev() y los iteradores, y cómo no romper tu código al trabajar con vectores y slices. ¡Allá vamos!
Error n.º 1: Uso ingenuo del rango en dirección inversa
\n\nEl error más común es intentar escribir for i in 10..0 esperando que Rust entienda: «ah, el usuario quiere ir en orden inverso». Lamentablemente, en Rust el rango a..b siempre va de a a b sin incluir. Si a >= b, el rango está vacío.
// ❌ Error: bucle vacío\nfor i in 10..0 {\n println!("{}", i); // No imprimirá nada\n}\n\n¿Por qué ocurre esto? Rust es un lenguaje estricto. Los rangos no se invierten automáticamente. Esto se hace por rendimiento y previsibilidad. Si 10..0 funcionara como inverso, el compilador tendría que verificar cada número con «¿quizás el valor inicial es mayor que el final?», lo que ralentizaría los bucles normales.
Cómo solucionarlo: usa el método .rev()
\n\nLa forma correcta es crear un rango ascendente normal y luego llamar al método .rev(), que invierte el iterador:
// ✅ Correcto: usamos .rev()\nfor i in (0..10).rev() {\n println!("{}", i); // Imprimirá: 9, 8, 7, ..., 0\n}\n\nObserva que usamos (0..10).rev(), no 10..0. Los paréntesis son obligatorios, ya que 0..10.rev() llamaría al método sobre 10, no sobre el rango. Este es otro error común.
Error n.º 2: Olvidar los paréntesis alrededor del rango
\n\nEl método .rev() se llama sobre un iterador. El rango 0..10 es un iterador. Pero si escribes 0..10.rev(), Rust lo interpreta como 0..(10.rev()), y el número entero 10 no tiene el método rev(). El compilador dará un error:
// ❌ Error de compilación: el número no tiene el método rev()\nfor i in 0..10.rev() {\n // error[E0599]: no method named `rev` found for integer `i32`\n}\n\nLa solución es simple: usa paréntesis:
\n\n// ✅ Los paréntesis lo resuelven todo\nfor i in (0..10).rev() {\n println!("{}", i);\n}\n\nError n.º 3: Intentar invertir algo que no es un iterador
\n\nA veces los principiantes intentan aplicar .rev() directamente a un vector o array:
let numbers = vec![1, 2, 3, 4, 5];\n\n// ❌ Error: Vec no tiene el método rev()\nfor i in numbers.rev() {\n println!("{}", i);\n}\n\n.rev() es un método de iterador, no de colección. Para invertir un vector, primero debes obtener un iterador con .iter() o .into_iter(), y luego llamar a .rev():
let numbers = vec![1, 2, 3, 4, 5];\n\n// ✅ Correcto: obtenemos un iterador, luego lo invertimos\nfor i in numbers.iter().rev() {\n println!("{}", i); // Imprimirá: 5, 4, 3, 2, 1\n}\n\nSi necesitas ser dueño de los elementos (por ejemplo, para moverlos), usa .into_iter().rev():
let numbers = vec![1, 2, 3, 4, 5];\n\nfor i in numbers.into_iter().rev() {\n println!("{}", i); // numbers ahora