Ćwiczenie — używanie struktur
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 Employee
Contractor
. 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}]