È uscito il Corso Java Completo — usa il coupon JAVA2026 (fino al 30 giugno)

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.