Ir al contenido

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.

fn main() {
for i in 1..=5 {
println!("{i}");
}
}

Salida:

1
2
3
4
5
▶ Pruébalo tú mismo

1..=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.

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:

manzana
naranja
cereza
▶ Pruébalo tú mismo

Compá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: manzana
1: naranja
2: cereza
▶ Pruébalo tú mismo

La 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.

¿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 cada n valores, 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 10
▶ Pruébalo tú mismo

Fí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.

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 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
▶ Pruébalo tú mismo

Las 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.

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 2500
▶ Pruébalo tú mismo

Otra 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.

  • for elemento in rango_o_colección { ... } es el bucle de todos los días en Rust.
  • 1..=5 incluye los dos extremos; 1..5 se 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..=1 está vacío. Usa (1..=3).rev() para contar hacia atrás, y .step_by(n) para avanzar a saltos.

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