Oefening: structs gebruiken
Er zijn momenten waarop u een verzameling velden in één structuur moet vertegenwoordigen. Wanneer u bijvoorbeeld een salarisadministratieprogramma moet schrijven, moet u een gegevensstructuur van werknemers gebruiken. In Go kunt u structs gebruiken om verschillende velden te groeperen die een record kunnen vormen.
Een struct in Go is een ander gegevenstype dat nul of meer velden van willekeurige typen kan bevatten en die als één entiteit kan vertegenwoordigen.
In deze sectie verkennen we waarom structs essentieel zijn en hoe u deze kunt gebruiken.
Een struct declareren en initialiseren
Als u een struct wilt declareren, moet u het struct
trefwoord gebruiken, samen met de lijst met velden en de bijbehorende typen die u het nieuwe gegevenstype wilt hebben. Als u bijvoorbeeld een werknemersstruct wilt definiëren, kunt u de volgende code gebruiken:
type Employee struct {
ID int
FirstName string
LastName string
Address string
}
Vervolgens kunt u een variabele declareren met het nieuwe type, zoals u meestal zou doen met andere typen, zoals deze:
var john Employee
En als u tegelijkertijd een variabele wilt declareren en initialiseren, kunt u dit op deze manier doen:
employee := Employee{1001, "John", "Doe", "Doe's Street"}
U moet een waarde opgeven voor elk van de velden uit de struct. Maar dat kan soms problematisch zijn. U kunt ook specifieker zijn over de velden die u wilt initialiseren in een struct:
employee := Employee{LastName: "Doe", FirstName: "John"}
U ziet dat de volgorde die u aan elk veld toewijst, niet van belang is vanuit de vorige instructie. Het maakt ook niet uit of u geen waarde opgeeft voor een ander veld. Go wijst een standaardwaarde toe, afhankelijk van het veldgegevenstype.
Als u toegang wilt krijgen tot afzonderlijke velden van een struct, kunt u dit doen met behulp van de punt notatie (.
), zoals in dit voorbeeld:
employee.ID = 1001
fmt.Println(employee.FirstName)
Ten slotte kunt u de &
operator gebruiken om een aanwijzer naar de struct te genereren, zoals in de volgende code wordt gedemonstreerd:
package main
import "fmt"
type Employee struct {
ID int
FirstName string
LastName string
Address string
}
func main() {
employee := Employee{LastName: "Doe", FirstName: "John"}
fmt.Println(employee)
employeeCopy := &employee
employeeCopy.FirstName = "David"
fmt.Println(employee)
}
Wanneer u de voorgaande code uitvoert, ziet u de volgende uitvoer:
{0 John Doe }
{0 David Doe }
U ziet hoe de struct veranderlijk wordt wanneer u aanwijzers gebruikt.
Insluiten van struct
Met Structs in Go kunt u een andere struct insluiten in een struct. Er zullen tijden zijn waarin u herhaling wilt verminderen en een gemeenschappelijke struct opnieuw wilt gebruiken. Stel dat u de vorige code wilt herstructureren om een gegevenstype voor een werknemer en een andere voor een contractant te hebben. U kunt een Person
struct hebben die algemene velden bevat, zoals in dit voorbeeld:
type Person struct {
ID int
FirstName string
LastName string
Address string
}
Vervolgens kunt u andere typen declareren die een Person
type insluiten, zoals een Employee
en een Contractor
. Als u een andere struct wilt insluiten, maakt u een nieuw veld, zoals in dit voorbeeld:
type Employee struct {
Information Person
ManagerID int
}
Als u echter wilt verwijzen naar een veld uit de Person
struct, moet u het Information
veld uit een werknemervariabele opnemen, zoals in dit voorbeeld:
var employee Employee
employee.Information.FirstName = "John"
Als u code herstructureert zoals we dat doen, wordt onze code hierdoor verbroken. U kunt ook een nieuw veld met dezelfde naam opnemen als de struct die u insluit, zoals in dit voorbeeld:
type Employee struct {
Person
ManagerID int
}
Als demonstratie kunt u de volgende code gebruiken:
package main
import "fmt"
type Person struct {
ID int
FirstName string
LastName string
Address string
}
type Employee struct {
Person
ManagerID int
}
type Contractor struct {
Person
CompanyID int
}
func main() {
employee := Employee{
Person: Person{
FirstName: "John",
},
}
employee.LastName = "Doe"
fmt.Println(employee.FirstName)
}
U ziet hoe u het FirstName
veld opent vanuit een Employee
struct zonder dat u het Person
veld hoeft op te geven omdat alle velden automatisch worden ingesloten. Maar wanneer u een struct initialiseert, moet u specifiek zijn over het veld waaraan u een waarde wilt toewijzen.
Structs coderen en decoderen met JSON
Ten slotte kunt u structs gebruiken om gegevens in JSON te coderen en decoderen. Go biedt uitstekende ondersteuning voor de JSON-indeling en deze is al opgenomen in de standaardbibliotheekpakketten.
U kunt ook dingen doen zoals de naam van een veld wijzigen vanuit de struct. Stel bijvoorbeeld dat u niet wilt dat de JSON-uitvoer wordt weergegeven FirstName
, maar gewoon name
lege velden negeert. U kunt veldtags zoals in dit voorbeeld gebruiken:
type Person struct {
ID int
FirstName string `json:"name"`
LastName string
Address string `json:"address,omitempty"`
}
Vervolgens gebruikt u de json.Marshal
functie om een struct in JSON te coderen. En als u een JSON-tekenreeks wilt decoderen in een gegevensstructuur, gebruikt u de json.Unmarshal
functie. Hier volgt een voorbeeld van een samenvoeging van alles, waarbij een matrix van werknemers wordt gecodeerd naar JSON en de uitvoer wordt gedecodering in een nieuwe variabele:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
ID int
FirstName string `json:"name"`
LastName string
Address string `json:"address,omitempty"`
}
type Employee struct {
Person
ManagerID int
}
type Contractor struct {
Person
CompanyID int
}
func main() {
employees := []Employee{
Employee{
Person: Person{
LastName: "Doe", FirstName: "John",
},
},
Employee{
Person: Person{
LastName: "Campbell", FirstName: "David",
},
},
}
data, _ := json.Marshal(employees)
fmt.Printf("%s\n", data)
var decoded []Employee
json.Unmarshal(data, &decoded)
fmt.Printf("%v", decoded)
}
Wanneer u de voorgaande code uitvoert, ziet u de volgende uitvoer:
[{"ID":0,"name":"John","LastName":"Doe","ManagerID":0},{"ID":0,"name":"David","LastName":"Campbell","ManagerID":0}]
[{{0 John Doe } 0} {{0 David Campbell } 0}]