In Go, le forme (o "struct") sono tipi di dati compositi che raggruppano zero o più campi nominati. Sono simili alle classi in altri linguaggi, ma Go non ha il concetto di eredità di classe. Le struct vengono utilizzate per rappresentare entità del mondo reale o concetti che hanno diversi attributi.
Definizione di una struct:
type Persona struct {
Nome string
Cognome string
Eta int
}
In questo esempio, Persona
è il nome della struct, e Nome
, Cognome
e Eta
sono i campi che la compongono, ognuno con un tipo specifico.
Creazione di istanze di struct:
Esistono diversi modi per creare istanze di struct:
Letterale struct:
p := Persona{Nome: "Mario", Cognome: "Rossi", Eta: 30}
Ordine dei campi: (Meno consigliato, in quanto sensibile all'ordine e meno leggibile)
p := Persona{"Mario", "Rossi", 30}
Utilizzo di new
:
p := new(Persona) // Crea un puntatore a una Persona con valori zero
p.Nome = "Mario"
p.Cognome = "Rossi"
p.Eta = 30
Accesso ai campi:
Si accede ai campi di una struct usando l'operatore punto (.
).
p := Persona{Nome: "Mario", Cognome: "Rossi", Eta: 30}
fmt.Println(p.Nome) // Stampa "Mario"
Se si ha un puntatore a una struct, si può ancora usare l'operatore punto per accedere ai campi. Go dereferenzia automaticamente il puntatore.
p := new(Persona)
p.Nome = "Mario"
fmt.Println(p.Nome) // Stampa "Mario"
Metodi:
Le struct possono avere metodi associati. Un metodo è una funzione che ha un ricevitore specificato tra la parola chiave func
e il nome del metodo. Il ricevitore specifica il tipo su cui il metodo opera.
type Persona struct {
Nome string
Cognome string
Eta int
}
func (p Persona) Saluta() string {
return "Ciao, mi chiamo " + p.Nome + " " + p.Cognome
}
func main() {
p := Persona{Nome: "Mario", Cognome: "Rossi", Eta: 30}
fmt.Println(p.Saluta()) // Stampa "Ciao, mi chiamo Mario Rossi"
}
Struct anonime:
Go supporta anche le struct anonime, che sono struct che non hanno un nome di tipo. Sono utili quando si ha bisogno di una struct solo localmente e non si vuole definire un tipo separato.
p := struct {
Nome string
Cognome string
}{
Nome: "Mario",
Cognome: "Rossi",
}
fmt.Println(p.Nome) // Stampa "Mario"
Campi embedded:
Go consente l'embedding di struct all'interno di altre struct. Questo permette di riutilizzare i campi e i metodi di una struct esistente all'interno di una nuova struct.
type Indirizzo struct {
Via string
Citta string
CAP string
}
type Persona struct {
Nome string
Cognome string
Eta int
Indirizzo Indirizzo // Indirizzo è embedded in Persona
}
func main() {
p := Persona{
Nome: "Mario",
Cognome: "Rossi",
Eta: 30,
Indirizzo: Indirizzo{
Via: "Via Roma, 1",
Citta: "Roma",
CAP: "00100",
},
}
fmt.Println(p.Indirizzo.Citta) // Stampa "Roma"
}
Si può anche avere un campo embedded anonimo:
type Indirizzo struct {
Via string
Citta string
CAP string
}
type Persona struct {
Nome string
Cognome string
Eta int
Indirizzo // Indirizzo è embedded anonimamente in Persona
}
func main() {
p := Persona{
Nome: "Mario",
Cognome: "Rossi",
Eta: 30,
Indirizzo: Indirizzo{
Via: "Via Roma, 1",
Citta: "Roma",
CAP: "00100",
},
}
fmt.Println(p.Citta) // Stampa "Roma" (accesso diretto)
}
L'accesso diretto ai campi embedded anonimi è possibile perché Go "promuove" i campi della struct embedded nella struct esterna.
Considerazioni importanti:
Spero che queste informazioni siano utili!