Range in Go
La keyword range in Go viene utilizzata nei cicli for per iterare su strutture dati come array, slice, mappe, stringhe e canali. Ad ogni iterazione restituisce l’indice (o chiave) e il valore dell’elemento corrente.
Range su Slice e Array
numeri := []int{10, 20, 30, 40, 50}
for indice, valore := range numeri {
fmt.Printf("Indice: %d, Valore: %d\n", indice, valore)
}
Solo Indice
Se non serve il valore, basta omettere la seconda variabile:
nomi := []string{"Alice", "Bob", "Carlo"}
for i := range nomi {
fmt.Printf("Indice: %d\n", i)
}
Solo Valore
Se non serve l’indice, si usa il blank identifier _:
numeri := []int{10, 20, 30}
for _, valore := range numeri {
fmt.Println(valore)
}
Range su Mappe
Con le mappe, range restituisce chiave e valore:
capitali := map[string]string{
"Italia": "Roma",
"Francia": "Parigi",
"Spagna": "Madrid",
}
for paese, capitale := range capitali {
fmt.Printf("%s → %s\n", paese, capitale)
}
Nota: l’ordine di iterazione su una mappa non è garantito.
Range su Stringhe
Iterando su una stringa, range restituisce l’indice del byte e la rune (carattere Unicode):
for indice, carattere := range "Ciao 🌍" {
fmt.Printf("Byte %d: %c (U+%04X)\n", indice, carattere, carattere)
}
Questo gestisce correttamente i caratteri multi-byte come le emoji.
Range su Canali
range su un canale riceve valori fino alla chiusura del canale:
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
for valore := range ch {
fmt.Println(valore)
}
// Stampa: 1, 2, 3
Range su Interi (Go 1.22+)
A partire da Go 1.22, si può usare range direttamente con un intero:
for i := range 5 {
fmt.Println(i) // 0, 1, 2, 3, 4
}
Equivale a for i := 0; i < 5; i++ ma piĂą conciso.
Attenzione: Copia dei Valori
range restituisce una copia del valore, non un riferimento:
numeri := []int{1, 2, 3}
for _, v := range numeri {
v *= 2 // Modifica solo la copia, non lo slice originale
}
fmt.Println(numeri) // [1 2 3] - invariato
// Per modificare, usa l'indice:
for i := range numeri {
numeri[i] *= 2
}
fmt.Println(numeri) // [2 4 6]
Conclusione
range è lo strumento idiomatico in Go per iterare su qualsiasi collezione. Fornisce una sintassi pulita e sicura, gestisce automaticamente i confini delle strutture dati ed è particolarmente utile con stringhe Unicode e canali. Ricorda che restituisce copie dei valori, non riferimenti diretti.