For en Rust
for recorre un rango o una colección, un elemento cada vez. De los tres tipos de bucle de Rust, es el que más vas a usar.
Recorrer un rango
Sección titulada «Recorrer un rango»fn main() { for i in 1..=5 { println!("{i}"); }}Salida:
123451..=5 es un rango que incluye los dos extremos (del 1 al 5). Si quitas el = y escribes 1..5, se queda uno antes y te da del 1 al 4. Es muy fácil equivocarse por uno, así que vale la pena comprobar cuál de los dos querías.
Recorrer una colección
Sección titulada «Recorrer una colección»Aquí es donde for brilla de verdad: recorrer un array o un vector sin tener que llevar tú la cuenta del índice:
fn main() { let fruits = ["manzana", "naranja", "cereza"];
for fruit in fruits { println!("{fruit}"); }}Salida:
manzananaranjacerezaCompáralo con contar a mano en un bucle while y acceder por índice (fruits[i]): es más corto y no hay ningún índice con el que equivocarse. Aprenderás más sobre arrays y vectores en las páginas de Arrays y Vectores.
Obtener también el índice con .enumerate()
Sección titulada «Obtener también el índice con .enumerate()»Si necesitas tanto la posición como el valor, usa .enumerate():
fn main() { let fruits = ["manzana", "naranja", "cereza"];
for (index, fruit) in fruits.iter().enumerate() { println!("{index}: {fruit}"); }}Salida:
0: manzana1: naranja2: cerezaLa parte (index, fruit) es un patrón de tupla: en cada vuelta recibes un par, y el bucle lo separa por ti en dos variables.
Contar hacia atrás y a saltos
Sección titulada «Contar hacia atrás y a saltos»¿Y si quieres contar hacia atrás desde 3, o visitar solo uno de cada dos números? Lo primero que se te ocurre es un rango al revés, como 3..=1. Compila, pero el bucle nunca se ejecuta. Un rango solo cuenta hacia arriba, así que un rango cuyo inicio es mayor que su final simplemente está vacío.
En su lugar, toma un rango normal y cambia la forma de recorrerlo:
.rev()recorre el rango al revés..step_by(n)toma uno de cadanvalores, empezando por el primero.
fn main() { for i in (1..=3).rev() { println!("{i}..."); } println!("¡Ya!");
for even in (0..=10).step_by(2) { print!("{even} "); } println!();
for i in 3..=1 { println!("esto nunca se imprime: {i}"); }}Salida:
3...2...1...¡Ya!0 2 4 6 8 10Fíjate en los paréntesis: (1..=3).rev(). Sin ellos, Rust leería 1..=3.rev() como “de 1 hasta 3.rev()”, que no es lo que quieres. También puedes combinar los dos: (0..=10).rev().step_by(5) da 10, 5, 0.
Por qué se prefiere for a while para contar
Sección titulada «Por qué se prefiere for a while para contar»Podrías escribir un bucle que cuenta con while, pero for con un rango elimina toda una familia de errores: no hay un contador que se te olvide actualizar, ni riesgo de pasarte un paso del final de un array. Quienes programan en Rust usan for por defecto, y solo recurren a while cuando no hay un rango o una colección natural que recorrer.
Práctica
Sección titulada «Práctica»1. Una tabla de multiplicar
Sección titulada «1. Una tabla de multiplicar»Imprime la tabla del 7, desde 7 x 1 = 7 hasta 7 x 10 = 70. Pista: basta con un bucle for sobre 1..=10. Puedes hacer la multiplicación directamente dentro de println!.
Ver solución
fn main() { for i in 1..=10 { println!("7 x {i} = {}", 7 * i); }}Salida:
7 x 1 = 77 x 2 = 147 x 3 = 217 x 4 = 287 x 5 = 357 x 6 = 427 x 7 = 497 x 8 = 567 x 9 = 637 x 10 = 70Las variables con nombre, como {i}, pueden ir directamente dentro de las llaves. Un cálculo como 7 * i no puede, así que se usa un {} vacío y el valor va después de la coma.
2. Suma los números impares
Sección titulada «2. Suma los números impares»Suma todos los números impares del 1 al 99 e imprime el total. Pista: (1..100).step_by(2) te da 1, 3, 5, … 99. Guarda un total mut fuera del bucle.
Ver solución
fn main() { let mut total = 0;
for n in (1..100).step_by(2) { total += n; }
println!("Los impares del 1 al 99 suman {total}");}Salida:
Los impares del 1 al 99 suman 2500Otra forma es recorrer 1..100 y sumar n solo cuando n % 2 == 1. Las dos funcionan. step_by simplemente se salta los pares en lugar de comprobar cada número.
Resumen
Sección titulada «Resumen»for elemento in rango_o_colección { ... }es el bucle de todos los días en Rust.1..=5incluye los dos extremos;1..5se queda uno antes del 5.- Recorre directamente arrays y vectores para obtener cada valor sin índices manuales.
- Usa
.enumerate()cuando necesites el índice junto al valor. - Un rango al revés como
3..=1está vacío. Usa(1..=3).rev()para contar hacia atrás, y.step_by(n)para avanzar a saltos.
Comprueba lo que aprendiste
Sección titulada «Comprueba lo que aprendiste»Comprueba lo aprendido
1. ¿Qué diferencia hay entre 1..=5 y 1..5 en un bucle for?
2. ¿Cómo obtienes a la vez el índice y el valor al recorrer una colección?
3. ¿Por qué se suele preferir for a while para recorrer una colección?
4. ¿Qué hace for i in 5..=1 { ... }?
Puntuación: 0 / 4
Para leer más
Sección titulada «Para leer más»- Recorrer una colección con for — El libro de Rust (en inglés): la introducción oficial, con una cuenta atrás usando
.rev(). - for y rangos — Rust by Example (en inglés): ejemplos ejecutables con rangos, además de
iter,iter_muteinto_iterpara colecciones. - Bucles con iteradores — The Rust Reference (en inglés): las reglas exactas de lo que hace un bucle
forpor debajo. Iterator::step_by— documentación de la biblioteca estándar (en inglés): cómo funcionastep_by, con ejemplos.revestá documentado en la misma página.