Cvičení – použití struktur
Někdy potřebujete reprezentovat kolekci polí v jedné struktuře. Pokud například potřebujete napsat mzdový program, musíte použít datovou strukturu zaměstnanců. V go můžete pomocí struktur seskupit různá pole, která by mohla vytvořit záznam.
Struktura v Go je jiný datový typ, který může obsahovat nula nebo více polí libovolných typů a představuje je jako jedna entita.
V této části prozkoumáme, proč jsou struktury nezbytné a jak je používat.
Deklarace a inicializace struktury
Chcete-li deklarovat strukturu, musíte použít struct
klíčové slovo spolu se seznamem polí a jejich typy, které chcete mít nový datový typ. Například k definování struktury zaměstnance můžete použít následující kód:
type Employee struct {
ID int
FirstName string
LastName string
Address string
}
Pak můžete deklarovat proměnnou s novým typem, jak byste to obvykle dělali s jinými typy, například takto:
var john Employee
A pokud chcete deklarovat a inicializovat proměnnou současně, můžete to udělat tímto způsobem:
employee := Employee{1001, "John", "Doe", "Doe's Street"}
Všimněte si, že je nutné zadat hodnotu pro každé pole ze struktury. Ale to může být někdy problematické. Případně můžete být konkrétnější o polích, která chcete inicializovat ve struktuře:
employee := Employee{LastName: "Doe", FirstName: "John"}
Všimněte si, že z předchozího příkazu nezáleží na pořadí, ve které přiřadíte hodnoty jednotlivým polím. Nezáleží také na tom, jestli nezadáte hodnotu pro žádné jiné pole. Go přiřadí výchozí hodnotu v závislosti na datovém typu pole.
Pokud chcete získat přístup k jednotlivým polím struktury, můžete to udělat pomocí zápisu tečky (.
), například v tomto příkladu:
employee.ID = 1001
fmt.Println(employee.FirstName)
Nakonec můžete pomocí operátoru &
vytvořit ukazatel na strukturu, například následující kód ukazuje:
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)
}
Při spuštění předchozího kódu se zobrazí následující výstup:
{0 John Doe }
{0 David Doe }
Všimněte si, jak se struktura při použití ukazatelů změní na proměnlivou strukturu.
Vkládání struktur
Struktury v go umožňují vložit jinou strukturu do struktury. Existují situace, kdy chcete snížit opakování a znovu použít společnou strukturu. Řekněme například, že chcete refaktorovat předchozí kód tak, aby měl datový typ pro zaměstnance a jiný pro dodavatele. Můžete mít Person
strukturu, která obsahuje běžná pole, například v tomto příkladu:
type Person struct {
ID int
FirstName string
LastName string
Address string
}
Pak můžete deklarovat jiné typy, které vkládají Person
typ, například typ Employee
a Contractor
. Pokud chcete vložit jinou strukturu, vytvořte nové pole, například v tomto příkladu:
type Employee struct {
Information Person
ManagerID int
}
Pokud ale chcete odkazovat na pole ze Person
struktury, budete muset zahrnout Information
pole z proměnné zaměstnance, například v tomto příkladu:
var employee Employee
employee.Information.FirstName = "John"
Pokud refaktorujete kód, jako bychom to dělali, přerušilo by to náš kód. Alternativně můžete zahrnout nové pole se stejným názvem struktury, kterou vkládáte, například v tomto příkladu:
type Employee struct {
Person
ManagerID int
}
Jako ukázku můžete použít následující kód:
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)
}
Všimněte si, jak se k poli dostanete FirstName
ze Employee
struktury, aniž byste museli zadat Person
pole, protože vkládá všechna jeho pole automaticky. Když ale inicializujete strukturu, musíte být specifická pro pole, ke kterému chcete přiřadit hodnotu.
Kódování a dekódování struktur pomocí JSON
Nakonec můžete pomocí struktur kódovat a dekódovat data ve formátu JSON. Go má vynikající podporu pro formát JSON a je již součástí standardních balíčků knihovny.
Můžete také udělat věci, jako je přejmenování názvu pole ze struktury. Řekněme například, že nechcete, aby výstup JSON zobrazoval FirstName
, ale jednoduše name
nebo ignoroval prázdná pole. Značky polí, jako je tento příklad, můžete použít:
type Person struct {
ID int
FirstName string `json:"name"`
LastName string
Address string `json:"address,omitempty"`
}
Potom k kódování struktury do FORMÁTU JSON použijete json.Marshal
funkci. A k dekódování řetězce JSON do datové struktury použijete json.Unmarshal
funkci. Tady je příklad, který všechno spojí dohromady, zakóduje pole zaměstnanců do FORMÁTU JSON a dekóduje výstup do nové proměnné:
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)
}
Při spuštění předchozího kódu se zobrazí následující výstup:
[{"ID":0,"name":"John","LastName":"Doe","ManagerID":0},{"ID":0,"name":"David","LastName":"Campbell","ManagerID":0}]
[{{0 John Doe } 0} {{0 David Campbell } 0}]