Oefening: structs gebruiken

Voltooid

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}]