Break e Continue in Go
Le istruzioni break e continue in Go permettono di controllare il flusso di esecuzione all’interno dei cicli. Mentre break interrompe completamente il ciclo, continue salta il resto dell’iterazione corrente e passa alla successiva. In Go, queste istruzioni possono anche essere combinate con le etichette (labels) per controllare cicli nidificati. Vediamo come funzionano in dettaglio.
L’Istruzione break
L’istruzione break termina immediatamente il ciclo for piu interno in cui si trova.
package main
import "fmt"
func main() {
for i := 0; i < 100; i++ {
if i == 5 {
break
}
fmt.Println(i)
}
fmt.Println("Ciclo terminato")
}
Output:
0
1
2
3
4
Ciclo terminato
Quando il valore di i raggiunge 5, il break interrompe il ciclo e l’esecuzione prosegue con l’istruzione successiva al ciclo.
L’Istruzione continue
L’istruzione continue salta il resto del corpo del ciclo e procede con la prossima iterazione.
for i := 0; i < 10; i++ {
if i%3 == 0 {
continue
}
fmt.Println(i)
}
Output:
1
2
4
5
7
8
In questo esempio, tutti i multipli di 3 vengono saltati grazie a continue.
Utilizzo di break nei Cicli Infiniti
Il break e fondamentale nei cicli infiniti per definire la condizione di uscita all’interno del corpo del ciclo.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Digita 'esci' per terminare:")
for {
fmt.Print("> ")
scanner.Scan()
input := scanner.Text()
if input == "esci" {
break
}
fmt.Println("Hai scritto:", input)
}
fmt.Println("Programma terminato")
}
Etichette (Labels) con break
Nei cicli nidificati, break interrompe solo il ciclo piu interno. Per uscire da un ciclo esterno, si usano le etichette.
package main
import "fmt"
func main() {
CicloEsterno:
for i := 0; i < 5; i++ {
for j := 0; j < 5; j++ {
if i+j == 6 {
fmt.Printf("Uscita a i=%d, j=%d\n", i, j)
break CicloEsterno
}
fmt.Printf("(%d, %d) ", i, j)
}
fmt.Println()
}
fmt.Println("Fuori da entrambi i cicli")
}
L’etichetta CicloEsterno: viene dichiarata immediatamente prima del ciclo esterno. Quando break CicloEsterno viene eseguito, entrambi i cicli vengono interrotti.
Etichette con continue
Allo stesso modo, continue con un’etichetta permette di saltare alla prossima iterazione di un ciclo esterno.
package main
import "fmt"
func main() {
Righe:
for riga := 0; riga < 4; riga++ {
for colonna := 0; colonna < 4; colonna++ {
if colonna == 2 {
continue Righe // Salta il resto della riga
}
fmt.Printf("[%d,%d] ", riga, colonna)
}
fmt.Println() // Questa riga non viene mai raggiunta
}
}
Output:
[0,0] [0,1] [1,0] [1,1] [2,0] [2,1] [3,0] [3,1]
In questo esempio, quando colonna vale 2, il continue Righe salta alla prossima iterazione del ciclo esterno, ignorando le colonne rimanenti e il fmt.Println().
Controllo di Cicli Nidificati: Esempio Pratico
Un caso d’uso tipico e la ricerca di un elemento in una matrice.
package main
import "fmt"
func main() {
matrice := [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
obiettivo := 5
trovato := false
Ricerca:
for i, riga := range matrice {
for j, valore := range riga {
if valore == obiettivo {
fmt.Printf("Trovato %d alla posizione [%d][%d]\n", obiettivo, i, j)
trovato = true
break Ricerca
}
}
}
if !trovato {
fmt.Println("Elemento non trovato")
}
}
Senza l’etichetta, il break avrebbe interrotto solo il ciclo interno, e il ciclo esterno avrebbe continuato l’iterazione inutilmente.
Differenza tra break in switch e in for
In Go, break all’interno di uno switch esce dallo switch, non dal ciclo che lo contiene. Per uscire dal ciclo, serve un’etichetta.
package main
import "fmt"
func main() {
Ciclo:
for i := 0; i < 10; i++ {
switch i {
case 5:
fmt.Println("Uscita dal ciclo for alla posizione", i)
break Ciclo // Esce dal for, non solo dallo switch
default:
fmt.Println("Valore:", i)
}
}
}
Conclusione
Le istruzioni break e continue sono strumenti essenziali per il controllo del flusso nei cicli in Go. Le etichette aggiungono un livello di controllo fondamentale per gestire cicli nidificati, permettendo di interrompere o continuare un ciclo specifico. Il caso del break all’interno di uno switch dentro un for e un pattern che ogni programmatore Go deve conoscere per evitare comportamenti inattesi.