Salta ai contenuti

Ciclo while in Rust

Un ciclo while continua a girare finché una condizione resta true. È lo strumento giusto quando sai che cosa stai aspettando, anche se non sai esattamente quante ripetizioni serviranno.

fn main() {
let mut count = 1;
while count <= 5 {
println!("{count}");
count += 1;
}
}

Output:

1
2
3
4
5
▶ Provalo tu

La condizione (count <= 5) viene controllata prima di ogni giro del ciclo. Appena diventa false, il ciclo finisce: qui, dopo che count è diventato 6.

Potresti scrivere la stessa cosa con loop e un if/break a mano, ma while dice in modo più diretto quello che intendi: «continua finché questo è vero». Tieni loop per i casi in cui la condizione di uscita non sta bene in cima al ciclo.

// con while: chiaro e diretto
let mut n = 0;
while n < 3 {
println!("{n}");
n += 1;
}
// la stessa cosa con loop: funziona, ma c'è più da leggere
let mut n = 0;
loop {
if n >= 3 {
break;
}
println!("{n}");
n += 1;
}

while si usa spesso per aspettare che un valore raggiunga un obiettivo:

fn main() {
let mut balance = 100;
while balance < 200 {
balance += 25;
println!("Il saldo ora è {balance}");
}
println!("Obiettivo raggiunto!");
}

Output:

Il saldo ora è 125
Il saldo ora è 150
Il saldo ora è 175
Il saldo ora è 200
Obiettivo raggiunto!
▶ Provalo tu

La condizione può essere qualsiasi espressione che dà un bool, quindi puoi combinare più controlli con && e || della pagina sugli Operatori, per esempio while balance < 200 && months < 12.

Alcuni linguaggi hanno un ciclo do { ... } while (condizione). Esegue il corpo prima e controlla la condizione dopo, quindi il corpo gira sempre almeno una volta. Rust non ce l’ha. Al suo posto usi loop e metti il controllo alla fine.

Ecco un caso in cui la differenza conta. Per contare le cifre di un numero puoi continuare a dividerlo per 10 finché non resta niente. Però il numero 0 ha comunque una cifra, e un semplice ciclo while per lui non parte mai:

fn main() {
let number = 0;
// Un ciclo while controlla prima, quindi con 0 non gira mai.
let mut n = number;
let mut digits = 0;
while n > 0 {
digits += 1;
n /= 10;
}
println!("secondo while {number} ha {digits} cifre");
// loop + un controllo alla fine esegue il corpo almeno una volta.
let mut n = number;
let mut digits = 0;
loop {
digits += 1;
n /= 10;
if n == 0 {
break;
}
}
println!("secondo loop {number} ha {digits} cifra");
}

Output:

secondo while 0 ha 0 cifre
secondo loop 0 ha 1 cifra
▶ Provalo tu

Cambia number in 4096 e le due versioni vanno d’accordo: 4 cifre. La differenza si vede solo quando la condizione è falsa fin dall’inizio. Quindi la regola pratica è: se il corpo deve girare almeno una volta, scrivi loop con if ... { break; } in fondo.

Esiste anche un altro tipo di ciclo while, while let, che continua finché un valore corrisponde a un pattern. Lo trovi nella pagina If let e while let.

Somma 1 + 2 + 3 + … e fermati appena il totale è maggiore di 100. Stampa quanti numeri hai sommato e il totale. Suggerimento: ti servono due variabili mut, una per il prossimo numero e una per il totale.

Mostra la soluzione
fn main() {
let mut next = 1;
let mut total = 0;
while total <= 100 {
total += next;
next += 1;
}
println!("Sommati {} numeri, il totale è {total}", next - 1);
}

Output:

Sommati 14 numeri, il totale è 105
▶ Provalo tu

Dopo l’ultimo giro, next è già andato avanti di un passo: per questo stampiamo next - 1. Vale la pena controllare questi dettagli «sfasati di uno» con un piccolo esempio a mente.

Parti da 1000. Finché il numero è maggiore di 1, dividilo per 2 (divisione intera) e stampalo. Alla fine stampa quanti dimezzamenti ci sono voluti. Suggerimento: n /= 2 divide n per 2 e scarta il resto.

Mostra la soluzione
fn main() {
let mut n = 1000;
let mut steps = 0;
while n > 1 {
n /= 2;
steps += 1;
println!("{n}");
}
println!("Ci sono voluti {steps} dimezzamenti per arrivare a 1");
}

Output:

500
250
125
62
31
15
7
3
1
Ci sono voluti 9 dimezzamenti per arrivare a 1
▶ Provalo tu

125 / 2 fa 62, non 62.5, perché entrambi i numeri sono interi. È proprio questo che fa finire il ciclo esattamente a 1.

  • while condizione { ... } ripete finché la condizione è true, e la controlla prima di ogni giro.
  • Assicurati che qualcosa dentro il ciclo prima o poi renda la condizione false, altrimenti girerà per sempre.
  • Preferisci while a loop quando la condizione di uscita si esprime in modo naturale come «finché X è vero».
  • Rust non ha il do-while. Quando il corpo deve girare almeno una volta, usa loop con il controllo del break alla fine.

Verifica veloce

1. Qual è l'errore classico che causa un ciclo while infinito?

2. Secondo questa pagina, quando conviene preferire while a loop?

3. Come scrivi un ciclo il cui corpo gira sempre almeno una volta?

Punteggio: 0 / 3