Struktury zagnieżdżone
Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 16 z 107.
Zagnieżdżona struktura to struktura, która zawiera inną nazwaną strukturę jako jedno ze swoich pól. Pozwala to modelować złożone, hierarchiczne dane przez łączenie mniejszych, wielokrotnego użytku typów.
type Address struct {
Street string
City string
ZIP string
}
type Person struct {
Name string
Age int
Address Address // zagnieżdżona struktura
}Aby uzyskać dostęp do pól w zagnieżdżonej strukturze, łączysz nazwy pól kropkami.
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
Street: "123 Main St",
City: "Boston",
ZIP: "02101",
},
}
fmt.Println(p.Address.City) // BostonZagnieżdżanie sprzyja ponownemu wykorzystaniu kodu. Typu Address można używać w wielu strukturach, takich jak Person, Company czy Order, bez powielania pól. To podejście odzwierciedla rzeczywiste relacje, w których encje zawierają inne encje.
type Company struct {
Name string
Employees int
Address Address // ponownie użyty ten sam typ Address
}Możesz zagnieżdżać struktury na wielu poziomach, choć płytkie hierarchie poprawiają czytelność. Zagnieżdżone struktury są podstawą tworzenia obiektowych modeli danych w Go.
Wyzwanie
ŁatwyZbudujmy system zarządzania pracownikami, który pokazuje, jak zagnieżdżone struktury pomagają modelować hierarchie z prawdziwego świata. Utworzysz strukturę, w której pracownicy należą do działów, a działy mają informacje o lokalizacji.
Rozmieścisz kod w dwóch plikach:
models.go: Zdefiniuj trzy współpracujące ze sobą struktury:Locationz polamiBuilding(string) iFloor(int)Departmentz polemName(string) oraz zagnieżdżonym polemLocationEmployeez polamiID(int),Name(string) oraz zagnieżdżonym polemDepartment
main.go: Wczytaj informacje o pracowniku z danych wejściowych, utwórz strukturę Employee z prawidłowo zagnieżdżonymi strukturami i wyświetl kompletny profil pracownika, uzyskując dostęp do pól za pośrednictwem zagnieżdżonej struktury.
Dane wejściowe będą następujące:
- Wiersz 1: ID pracownika (liczba całkowita)
- Wiersz 2: Imię i nazwisko pracownika
- Wiersz 3: Nazwa działu
- Wiersz 4: Nazwa budynku
- Wiersz 5: Numer piętra (liczba całkowita)
Format wyjściowy:
Employee: [Name] (ID: [ID])
Department: [DepartmentName]
Location: [Building], Floor [Floor]Na przykład dla danych 101, Alice Chen, Engineering, Tower A i 5 wynik powinien wyglądać następująco:
Employee: Alice Chen (ID: 101)
Department: Engineering
Location: Tower A, Floor 5Uzyskaj dostęp do zagnieżdżonych pól, używając notacji kropkowej do przechodzenia przez hierarchię struktur (np. employee.Department.Location.Building).
Spróbuj swoich sił
package main
import "fmt"
func main() {
// Wczytaj informacje o pracowniku
var id int
var name string
var deptName string
var building string
var floor int
fmt.Scanln(&id)
fmt.Scanln(&name)
fmt.Scanln(&deptName)
fmt.Scanln(&building)
fmt.Scanln(&floor)
// TODO: Utwórz Employee z poprawnie zagnieżdżonymi strukturami
// Użyj struktur Location, Department i Employee z pliku models.go
// Zainicjalizuj wszystkie zagnieżdżone pola wartościami wejściowymi
// TODO: Wyświetl profil pracownika w formacie:
// Pracownik: [Name] (ID: [ID])
// Dział: [DepartmentName]
// Lokalizacja: [Building], piętro [Floor]
// Uzyskaj dostęp do zagnieżdżonych pól za pomocą notacji kropkowej (np. employee.Department.Location.Building)
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP w Go
Pliki zewnętrzneObszar roboczy i moduły GoPakiety i importyNazwy eksportowane i nieeksportowaneWprowadzenie do OOP w GoStruktury jako klasyDefiniowanie metod dla strukturOdbiorniki wskaźnikowe i wartościoweInicjalizacja strukturFunkcje konstruktoraPodsumowanie – prosty kalkulator4Interfejsy
Wprowadzenie do interfejsówImplementacja niejawnaInterfejs jako kontraktPusty interfejs (any)Asercja typuPrzełącznik typówKompozycja interfejsówInterfejsy Stringer i ErrorPowtórka — kalkulator figur7Hermetyzacja
Pola eksportowane i nieeksportowaneHermetyzacja na poziomie pakietuMetody pobierające i ustawiająceUkrywanie informacji w GoPowtórka – dane studentów10Typy generyczne (Go 1.18+)
Wprowadzenie do typów generycznychParametry typówOgraniczenia typówStruktury generyczneObejście ograniczeń metod generycznychPodsumowanie — generyczna kolekcja2Typy i struktury w praktyce
Typy proste i złożoneDefiniowanie własnych typówTagi pól strukturStruktury anonimoweStruktury zagnieżdżoneWartości zerowe i domyślnePodsumowanie – książka kontaktów5Kompozycja zamiast dziedziczenia
Dlaczego Go nie ma dziedziczeniaPodstawy osadzania strukturPromowanie metodOsadzanie wielu strukturOsadzanie a agregacjaPrzesłanianie osadzonych metodPodsumowanie — hierarchia pracowników8Obsługa błędów i programowanie obiektowe
Interfejs błęduWłasne typy błędówOpakowywanie błędów (fmt.Errorf)Błędy wartowniczeerrors.Is() i errors.As()Panic, Defer i RecoverPodsumowanie — parser plików3Wskaźniki i pamięć
Podstawy wskaźników w GoWskaźniki do strukturPrzekazywanie przez wartość a przez referencjęFunkcja new()Odśmiecanie pamięci w GoPowtórka — kreator listy wiązanej6Polimorfizm w Go
Polimorfizm za pomocą interfejsówDuck typing w GoZasady spełniania interfejsówKolekcje polimorficzneWstrzykiwanie zależnościPowtórka — procesor płatności9Współbieżność i OOP
Podstawy goroutinesKanały i komunikacjaKanały buforowane i niebuforowaneInstrukcja selectsync.Mutex i sync.RWMutexsync.WaitGroupProjektowanie struktur bezpiecznych wątkowoPowtórka – pula workerów12Zaawansowane zagadnienia programowania obiektowego
Wzorzec opcji funkcyjnychWzorzec Builder w GoŁańcuchowe wywoływanie metodAliasy typów a definicje typówPodstawy refleksjiPrzegląd generowania koduPoćwicz samodzielnie: Kompilator Go online