Array in Go
Gli array in Go sono sequenze di elementi dello stesso tipo con una dimensione fissa, determinata al momento della compilazione. A differenza di molti altri linguaggi, in Go gli array sono tipi valore: quando vengono assegnati o passati a una funzione, viene creata una copia completa. In questa guida esploreremo dichiarazione, inizializzazione e utilizzo degli array.
Dichiarazione di un Array
Un array si dichiara specificando la dimensione tra parentesi quadre e il tipo degli elementi.
package main
import "fmt"
func main() {
var numeri [5]int // Array di 5 interi, inizializzati a 0
fmt.Println(numeri) // [0 0 0 0 0]
var nomi [3]string // Array di 3 stringhe, inizializzate a ""
fmt.Println(nomi) // [ ]
}
Gli elementi vengono automaticamente inizializzati al valore zero del tipo: 0 per gli interi, "" per le stringhe, false per i booleani.
Inizializzazione con Valori
Si puo inizializzare un array al momento della dichiarazione usando un letterale.
// Inizializzazione esplicita
numeri := [5]int{10, 20, 30, 40, 50}
fmt.Println(numeri) // [10 20 30 40 50]
// Inizializzazione parziale (gli altri sono valori zero)
parziale := [5]int{1, 2, 3}
fmt.Println(parziale) // [1 2 3 0 0]
// Dimensione inferita dal compilatore
auto := [...]int{100, 200, 300}
fmt.Println(auto) // [100 200 300]
Con [...] il compilatore conta automaticamente il numero di elementi e definisce la dimensione dell’array.
Inizializzazione con Indici Specifici
E possibile specificare i valori per indici specifici.
giorni := [7]string{
0: "Lunedi",
1: "Martedi",
2: "Mercoledi",
3: "Giovedi",
4: "Venerdi",
5: "Sabato",
6: "Domenica",
}
// Inizializzazione sparsa
codici := [10]int{1: 100, 5: 500, 9: 900}
fmt.Println(codici) // [0 100 0 0 0 500 0 0 0 900]
Accesso agli Elementi
Gli elementi di un array si accedono tramite l’indice, che parte da 0.
frutti := [4]string{"mela", "banana", "arancia", "uva"}
fmt.Println(frutti[0]) // mela
fmt.Println(frutti[2]) // arancia
// Modifica di un elemento
frutti[1] = "pera"
fmt.Println(frutti) // [mela pera arancia uva]
Accedere a un indice fuori dai limiti dell’array causa un panic a runtime.
Lunghezza di un Array
La funzione len() restituisce la lunghezza dell’array.
numeri := [6]int{10, 20, 30, 40, 50, 60}
fmt.Println("Lunghezza:", len(numeri)) // Lunghezza: 6
La lunghezza fa parte del tipo dell’array: [3]int e [5]int sono tipi diversi e incompatibili.
Iterazione con for Classico
voti := [5]float64{7.5, 8.0, 6.5, 9.0, 7.0}
for i := 0; i < len(voti); i++ {
fmt.Printf("Voto %d: %.1f\n", i+1, voti[i])
}
Iterazione con for range
Il costrutto for range e il modo idiomatico per iterare su un array.
colori := [4]string{"rosso", "verde", "blu", "giallo"}
for indice, colore := range colori {
fmt.Printf("Indice %d: %s\n", indice, colore)
}
// Solo i valori, senza l'indice
for _, colore := range colori {
fmt.Println(colore)
}
Array come Tipi Valore
Gli array in Go sono tipi valore. Quando si assegna un array a un’altra variabile o lo si passa a una funzione, viene creata una copia completa.
package main
import "fmt"
func modificaArray(arr [3]int) {
arr[0] = 999
fmt.Println("Dentro la funzione:", arr) // [999 2 3]
}
func main() {
originale := [3]int{1, 2, 3}
modificaArray(originale)
fmt.Println("Fuori dalla funzione:", originale) // [1 2 3]
}
L’array originale non viene modificato perche la funzione lavora su una copia. Per modificare l’originale, bisogna passare un puntatore.
func modificaConPuntatore(arr *[3]int) {
arr[0] = 999
}
func main() {
originale := [3]int{1, 2, 3}
modificaConPuntatore(&originale)
fmt.Println(originale) // [999 2 3]
}
Confronto tra Array
Gli array dello stesso tipo e dimensione possono essere confrontati con == e !=.
a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
c := [3]int{3, 2, 1}
fmt.Println(a == b) // true
fmt.Println(a == c) // false
Array Multidimensionali
Go supporta array multidimensionali, utili per rappresentare matrici e griglie.
package main
import "fmt"
func main() {
// Matrice 3x3
matrice := [3][3]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
// Accesso a un elemento
fmt.Println("Elemento [1][2]:", matrice[1][2]) // 6
// Iterazione sulla matrice
for i, riga := range matrice {
for j, valore := range riga {
fmt.Printf("matrice[%d][%d] = %d ", i, j, valore)
}
fmt.Println()
}
}
Quando Usare Array vs Slice
In Go, le slice sono molto piu comuni degli array. Gli array sono utili quando:
- La dimensione e nota e fissa al momento della compilazione
- Si desidera il comportamento di tipo valore (copie automatiche)
- Si lavora con strutture dati a basso livello o prestazioni critiche
Nella pratica quotidiana, le slice (che vedremo nella prossima guida) sono preferite per la loro flessibilita.
Conclusione
Gli array in Go hanno una dimensione fissa che fa parte del loro tipo. Sono tipi valore, il che significa che assegnazioni e passaggi a funzione creano copie complete. La dimensione fissa e il comportamento per valore li distinguono dalle slice. Sebbene le slice siano piu comunemente utilizzate, comprendere gli array e fondamentale perche le slice si basano internamente su di essi.