Break e continue in Rust
break e continue ti permettono di interrompere un ciclo prima del tempo, invece di farlo arrivare sempre fino in fondo. Funzionano allo stesso modo in tutti e tre i tipi di ciclo: loop, while e for.
break: uscire del tutto dal ciclo
Sezione intitolata “break: uscire del tutto dal ciclo”break ferma subito il ciclo, e l’esecuzione salta a quello che viene subito dopo:
fn main() { for i in 1..=10 { if i == 5 { break; } println!("{i}"); }}Output:
1234Anche se il range arriva fino a 10, il ciclo si ferma nel momento in cui i vale 5.
continue: saltare al giro successivo
Sezione intitolata “continue: saltare al giro successivo”continue salta il resto del giro corrente e passa direttamente al successivo, senza fermare il ciclo:
fn main() { for i in 1..=10 { if i % 2 == 0 { continue; // salta i numeri pari } println!("{i}"); }}Output:
13579Ogni numero pari viene saltato: scatta continue e il ciclo passa subito al valore successivo di i, senza eseguire println!.
Cicli con etichetta
Sezione intitolata “Cicli con etichetta”Quando metti un ciclo dentro un altro, break/continue da soli agiscono solo sul ciclo più interno. Se devi uscire da un ciclo esterno stando dentro quello annidato, dai al ciclo esterno un’etichetta (scritta come 'nome:):
fn main() { 'outer: for x in 1..=3 { for y in 1..=3 { if x * y > 4 { break 'outer; } println!("{x} x {y} = {}", x * y); } }}Output:
1 x 1 = 11 x 2 = 21 x 3 = 32 x 1 = 22 x 2 = 4Senza l’etichetta, break fermerebbe solo il ciclo interno su y, e x andrebbe avanti. break 'outer; li ferma entrambi in un colpo. continue 'outer; funziona allo stesso modo, se invece di fermarti vuoi passare al giro successivo del ciclo esterno.
La trappola di continue nei cicli while
Sezione intitolata “La trappola di continue nei cicli while”In un ciclo for il valore successivo arriva in automatico dal range, quindi continue è sempre sicuro. Un ciclo while è diverso: sei tu ad aggiornare il contatore, di solito in fondo al corpo. Se continue salta quell’aggiornamento, il contatore non cambia mai e il ciclo gira per sempre.
Questa versione prova a saltare il 3, ma si blocca. Non eseguirla:
fn main() { let mut i = 0; while i < 5 { if i == 3 { continue; // ❌ torna su senza cambiare i } println!("{i}"); i += 1; }}Quando i vale 3, continue torna alla condizione. i vale ancora 3, quindi continue scatta di nuovo, e poi ancora, all’infinito. La soluzione è aggiornare il contatore prima di qualsiasi cosa possa fare continue:
fn main() { let mut i = 0; while i < 5 { i += 1; // prima aggiorna, così continue non può saltarlo if i == 3 { continue; } println!("{i}"); }}Output:
1245Spostare i += 1 in cima sposta i numeri di uno: questo ciclo stampa da 1 a 5 invece che da 0 a 4, quindi correggi il valore iniziale o la condizione se ti serve il range di prima. Ancora meglio: se stai solo contando, usa un ciclo for su un range e il problema non può proprio presentarsi.
Pratica
Sezione intitolata “Pratica”1. Salta i multipli di 3
Sezione intitolata “1. Salta i multipli di 3”Stampa i numeri da 1 a 10, ma salta tutti i multipli di 3. Suggerimento: un numero è multiplo di 3 quando n % 3 == 0. Usa continue per saltarlo.
Mostra la soluzione
fn main() { for n in 1..=10 { if n % 3 == 0 { continue; } println!("{n}"); }}Output:
124578102. Trova una coppia che moltiplicata fa 24
Sezione intitolata “2. Trova una coppia che moltiplicata fa 24”Usa due cicli for annidati, x e y, entrambi su 1..=9. Trova la prima coppia per cui x * y == 24, stampala e ferma entrambi i cicli. Suggerimento: metti un’etichetta sul ciclo esterno e usa break 'outer;.
Mostra la soluzione
fn main() { 'outer: for x in 1..=9 { for y in 1..=9 { if x * y == 24 { println!("Trovata: {x} x {y} = 24"); break 'outer; } } } println!("Ricerca finita");}Output:
Trovata: 3 x 8 = 24Ricerca finitaProva a cambiare break 'outer; in un semplice break;. Ora si ferma solo il ciclo interno, quindi la ricerca continua e stampa anche 4 x 6, 6 x 4 e 8 x 3.
Riepilogo
Sezione intitolata “Riepilogo”breakesce subito dal ciclo.continuesalta il resto del giro corrente e passa al successivo.- Un’etichetta (
'outer:) permette abreak/continuedi agire su un ciclo esterno da dentro uno annidato. - In un ciclo
while, aggiorna il contatore prima di qualsiasicontinue, altrimenti il ciclo può bloccarsi per sempre.
Verifica veloce
Sezione intitolata “Verifica veloce”Verifica veloce
1. Che cosa fa continue dentro un ciclo?
2. Come scrivi l'etichetta di un ciclo, così che break possa riferirsi a lui da un ciclo annidato?
3. Un ciclo while con continue non finisce mai. Qual è la causa più probabile?
Punteggio: 0 / 3
Per approfondire
Sezione intitolata “Per approfondire”- Loop Labels to Disambiguate Between Multiple Loops — The Rust Book (in inglese): l’introduzione ufficiale alle etichette, con un conto alla rovescia annidato.
- Nesting and labels — Rust by Example (in inglese): un breve esempio eseguibile di
break 'outerecontinue 'outer. - Loop Labels — The Rust Reference (in inglese): le regole esatte su dove si possono usare le etichette.
breakexpressions — The Rust Reference (in inglese): come funzionabreak, anche con un valore.continueexpressions — The Rust Reference (in inglese): che cosa facontinuein ogni tipo di ciclo.