Ćwiczenie — używanie struktur

Ukończone

Czasami trzeba reprezentować kolekcję pól w jednej strukturze. Jeśli na przykład musisz napisać program płacowy, musisz użyć struktury danych pracowników. W języku Go można użyć struktur do grupowania różnych pól, które mogą utworzyć rekord.

Struktura w języku Go to inny typ danych, który może zawierać zero lub więcej pól dowolnego typu i reprezentować je jako pojedynczą jednostkę.

W tej sekcji dowiemy się, dlaczego struktury są niezbędne i jak ich używać.

Deklarowanie i inicjowanie struktury

Aby zadeklarować strukturę, należy użyć słowa kluczowego struct wraz z listą pól i ich typów, które mają mieć nowy typ danych. Na przykład w celu zdefiniowania struktury pracownika można użyć następującego kodu:

type Employee struct {
    ID        int
    FirstName string
    LastName  string
    Address   string
}

Następnie można zadeklarować zmienną o nowym typie, tak jak zwykle w przypadku innych typów, takich jak:

var john Employee

Jeśli chcesz zadeklarować i zainicjować zmienną w tym samym czasie, możesz to zrobić w następujący sposób:

employee := Employee{1001, "John", "Doe", "Doe's Street"}

Zwróć uwagę, że musisz określić wartość dla każdego pola z struktury. Ale to może być problematyczne czasami. Alternatywnie możesz bardziej szczegółowo określić pola, które chcesz zainicjować w ramach struktury:

employee := Employee{LastName: "Doe", FirstName: "John"}

Zwróć uwagę, że z poprzedniej instrukcji kolejność przypisywania wartości do każdego pola nie ma znaczenia. Ponadto nie ma znaczenia, jeśli nie określisz wartości dla żadnego innego pola. Funkcja Go przypisze wartość domyślną w zależności od typu danych pola.

Aby uzyskać dostęp do poszczególnych pól struktury, możesz to zrobić przy użyciu notacji kropkowej (.), takiej jak w tym przykładzie:

employee.ID = 1001
fmt.Println(employee.FirstName)

Na koniec możesz użyć & operatora , aby uzyskać wskaźnik do struktury, jak pokazano w poniższym kodzie:

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

Po uruchomieniu poprzedniego kodu zobaczysz następujące dane wyjściowe:

{0 John Doe }
{0 David Doe }

Zwróć uwagę, że struktura staje się modyfikowalna podczas używania wskaźników.

Osadzanie struktury

Struktury w języku Go umożliwiają osadzanie innej struktury w ramach struktury. Będą czasy, w których chcesz zmniejszyć powtarzanie i ponownie użyć wspólnej struktury. Załóżmy na przykład, że chcesz refaktoryzować poprzedni kod, aby mieć typ danych dla pracownika, a drugi dla wykonawcy. Możesz mieć strukturę zawierającą Person typowe pola, takie jak w tym przykładzie:

type Person struct {
    ID        int
    FirstName string
    LastName  string
    Address   string
}

Następnie można zadeklarować inne typy, które osadzają Person typ, na przykład i EmployeeContractor. Aby osadzić inną strukturę, należy utworzyć nowe pole, takie jak w tym przykładzie:

type Employee struct {
    Information Person
    ManagerID   int
}

Jednak aby odwołać się do pola z Person struktury, musisz uwzględnić Information pole ze zmiennej pracownika, tak jak w tym przykładzie:

var employee Employee
employee.Information.FirstName = "John"

Jeśli refaktoryzujesz kod, tak jak robimy, spowoduje to przerwanie kodu. Alternatywnie możesz dołączyć nowe pole o tej samej nazwie struktury, którą osadzasz, jak w tym przykładzie:

type Employee struct {
    Person
    ManagerID int
}

W ramach pokazu możesz użyć następującego kodu:

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

Zwróć uwagę, FirstName że uzyskujesz dostęp do pola z Employee struktury bez konieczności określania Person pola, ponieważ automatycznie osadza wszystkie pola. Jednak podczas inicjowania struktury trzeba być konkretnym polem, do którego chcesz przypisać wartość.

Kodowanie i dekodowanie struktur przy użyciu formatu JSON

Na koniec możesz użyć struktur do kodowania i dekodowania danych w formacie JSON. Go ma doskonałą obsługę formatu JSON i jest już zawarty w standardowych pakietach biblioteki.

Możesz również wykonać takie czynności, jak zmiana nazwy pola z struktury. Załóżmy na przykład, że dane wyjściowe JSON nie mają być wyświetlane FirstName , ale po prostu name lub ignorują puste pola. Możesz użyć tagów pól, takich jak w tym przykładzie:

type Person struct {
    ID        int    
    FirstName string `json:"name"`
    LastName  string
    Address   string `json:"address,omitempty"`
}

Następnie, aby zakodować strukturę w formacie JSON, należy użyć json.Marshal funkcji . Aby zdekodować ciąg JSON do struktury danych, należy użyć json.Unmarshal funkcji . Oto przykład, który łączy wszystkie elementy, kodując tablicę pracowników w formacie JSON i dekodując dane wyjściowe do nowej zmiennej:

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

Po uruchomieniu poprzedniego kodu zobaczysz następujące dane wyjściowe:

[{"ID":0,"name":"John","LastName":"Doe","ManagerID":0},{"ID":0,"name":"David","LastName":"Campbell","ManagerID":0}]
[{{0 John Doe } 0} {{0 David Campbell } 0}]