Salta ai contenuti

Ciclo for in Rust

for scorre un range o una collezione, un elemento alla volta. Dei tre tipi di ciclo di Rust, è quello che userai più spesso.

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

Output:

1
2
3
4
5
▶ Provalo tu

1..=5 è un range (intervallo) che include entrambi gli estremi (da 1 a 5). Se togli l’=, cioè 1..5, si ferma un passo prima e ti dà i numeri da 1 a 4. È facile inciampare in questo errore «di uno», quindi conviene controllare due volte quale dei due intendevi.

Qui for dà il meglio di sé: scorre un array o un vettore senza che tu debba tenere traccia di un indice:

fn main() {
let fruits = ["mela", "banana", "ciliegia"];
for fruit in fruits {
println!("{fruit}");
}
}

Output:

mela
banana
ciliegia
▶ Provalo tu

Confrontalo con il contare a mano in un ciclo while e usare un indice (fruits[i]): è più corto e non c’è nessun indice da sbagliare. Approfondirai array e vettori nelle pagine Array e Vettori.

Se ti servono sia la posizione sia il valore, usa .enumerate():

fn main() {
let fruits = ["mela", "banana", "ciliegia"];
for (index, fruit) in fruits.iter().enumerate() {
println!("{index}: {fruit}");
}
}

Output:

0: mela
1: banana
2: ciliegia
▶ Provalo tu

La parte (index, fruit) è un pattern di tupla: a ogni giro ricevi una coppia, e il ciclo la divide per te in due variabili.

E se vuoi contare alla rovescia da 3, o visitare solo un numero sì e uno no? Il primo tentativo naturale è un range che va all’indietro, come 3..=1. Compila, ma il ciclo non gira mai. Un range conta solo in avanti, quindi un range con l’inizio più grande della fine è semplicemente vuoto.

Prendi invece un range normale e cambia il modo in cui lo percorri:

  • .rev() percorre il range al contrario.
  • .step_by(n) prende un valore ogni n, a partire dal primo.
fn main() {
for i in (1..=3).rev() {
println!("{i}...");
}
println!("Via!");
for even in (0..=10).step_by(2) {
print!("{even} ");
}
println!();
for i in 3..=1 {
println!("questo non viene mai stampato: {i}");
}
}

Output:

3...
2...
1...
Via!
0 2 4 6 8 10
▶ Provalo tu

Fai caso alle parentesi: (1..=3).rev(). Senza, Rust leggerebbe 1..=3.rev() come «da 1 fino a 3.rev()», che non è quello che vuoi. Puoi anche combinare le due cose: (0..=10).rev().step_by(5) dà 10, 5, 0.

Potresti scrivere un ciclo che conta con while, ma for con un range elimina un’intera categoria di errori: nessun contatore manuale da dimenticare di aggiornare e nessun rischio di andare un passo oltre la fine di un array. Chi programma in Rust usa for di default e ricorre a while solo quando non c’è un range o una collezione naturale da scorrere.

Stampa la tabellina del 7, da 7 x 1 = 7 fino a 7 x 10 = 70. Suggerimento: basta un ciclo for su 1..=10. Puoi fare la moltiplicazione direttamente dentro println!.

Mostra la soluzione
fn main() {
for i in 1..=10 {
println!("7 x {i} = {}", 7 * i);
}
}

Output:

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
▶ Provalo tu

Le variabili con un nome, come {i}, possono andare direttamente tra le graffe. Un calcolo come 7 * i no, quindi si usa una {} vuota con il valore dopo la virgola.

Somma tutti i numeri dispari da 1 a 99 e stampa il totale. Suggerimento: (1..100).step_by(2) ti dà 1, 3, 5, … 99. Tieni un totale mut fuori dal ciclo.

Mostra la soluzione
fn main() {
let mut total = 0;
for n in (1..100).step_by(2) {
total += n;
}
println!("La somma dei numeri dispari da 1 a 99 è {total}");
}

Output:

La somma dei numeri dispari da 1 a 99 è 2500
▶ Provalo tu

Un altro modo è scorrere 1..100 e sommare n solo quando n % 2 == 1. Funzionano entrambi. step_by salta semplicemente i numeri pari invece di controllarli uno per uno.

  • for elemento in range_o_collezione { ... } è il ciclo di tutti i giorni in Rust.
  • 1..=5 include entrambi gli estremi; 1..5 si ferma prima del 5.
  • Scorri direttamente array e vettori per avere ogni valore senza indici manuali.
  • Usa .enumerate() quando ti serve l’indice insieme al valore.
  • Un range all’indietro come 3..=1 è vuoto. Usa (1..=3).rev() per contare alla rovescia e .step_by(n) per saltare valori.

Verifica veloce

1. Che differenza c'è tra 1..=5 e 1..5 in un ciclo for?

2. Come ottieni sia l'indice sia il valore mentre scorri una collezione?

3. Perché in genere si preferisce for a while per scorrere una collezione?

4. Che cosa fa for i in 5..=1 { ... }?

Punteggio: 0 / 4