Structs imbriquées
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 16 sur 107.
Une structure imbriquée est une structure qui contient une autre structure nommée comme l'un de ses champs. Cela vous permet de modéliser des données complexes et hiérarchiques en composant ensemble des types plus petits et réutilisables.
type Address struct {
Street string
City string
ZIP string
}
type Person struct {
Name string
Age int
Address Address // structure imbriquée
}Pour accéder aux champs d'une structure imbriquée, vous enchaînez les noms des champs avec des points.
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
Street: "123 Main St",
City: "Boston",
ZIP: "02101",
},
}
fmt.Println(p.Address.City) // BostonL'imbrication favorise la réutilisation du code. Le type Address peut être utilisé dans plusieurs structures comme Person, Company ou Order sans dupliquer les champs. Cette approche reflète les relations du monde réel où les entités contiennent d'autres entités.
type Company struct {
Name string
Employees int
Address Address // même type Address réutilisé
}Vous pouvez imbriquer des structures sur plusieurs niveaux, bien que le maintien de hiérarchies peu profondes améliore la lisibilité. Les structures imbriquées sont fondamentales pour construire des modèles de données orientés objet en Go.
Défi
FacileConstruisons un système de gestion des employés qui démontre comment les structures imbriquées aident à modéliser les hiérarchies du monde réel. Vous allez créer une structure où les employés appartiennent à des départements, et les départements possèdent des informations de localisation.
Vous organiserez votre code sur deux fichiers :
models.go: Définissez trois structures qui fonctionnent ensemble :Locationavec les champsBuilding(string) etFloor(int)Departmentavec un champName(string) et un champLocationimbriquéEmployeeavec les champsID(int),Name(string), et un champDepartmentimbriqué
main.go: Lisez les informations de l'employé à partir de l'entrée, créez un Employee avec les structures correctement imbriquées, et affichez le profil complet de l'employé en accédant aux champs via la structure imbriquée.
Les entrées suivantes seront fournies :
- Ligne 1 : ID de l'employé (entier)
- Ligne 2 : Nom de l'employé
- Ligne 3 : Nom du département
- Ligne 4 : Nom du bâtiment
- Ligne 5 : Numéro d'étage (entier)
Format de sortie :
Employee: [Name] (ID: [ID])
Department: [DepartmentName]
Location: [Building], Floor [Floor]Par exemple, avec 101, Alice Chen, Engineering, Tower A, et 5, votre sortie devrait être :
Employee: Alice Chen (ID: 101)
Department: Engineering
Location: Tower A, Floor 5Accédez aux champs imbriqués en utilisant la notation par points pour naviguer dans la hiérarchie des structures (par exemple, employee.Department.Location.Building).
Aide-mémoire
Une structure imbriquée (nested struct) est une structure qui contient une autre structure nommée comme l'un de ses champs, vous permettant de modéliser des données hiérarchiques en composant des types plus petits et réutilisables.
Définir des structures imbriquées
type Address struct {
Street string
City string
ZIP string
}
type Person struct {
Name string
Age int
Address Address // structure imbriquée
}Accéder aux champs imbriqués
Utilisez la notation par points pour parcourir la hiérarchie des structures :
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
Street: "123 Main St",
City: "Boston",
ZIP: "02101",
},
}
fmt.Println(p.Address.City) // BostonRéutiliser des structures imbriquées
Le même type de structure imbriquée peut être réutilisé dans plusieurs structures parentes :
type Company struct {
Name string
Employees int
Address Address // même type Address réutilisé
}Les structures imbriquées favorisent la réutilisation du code et reflètent les relations du monde réel où des entités en contiennent d'autres. Vous pouvez imbriquer des structures sur plusieurs niveaux, bien que le maintien de hiérarchies peu profondes améliore la lisibilité.
Essayez vous-même
package main
import "fmt"
func main() {
// Lire les informations de l'employé
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: Créer un Employee avec des structs correctement imbriquées
// Utiliser les structs Location, Department, et Employee de models.go
// Initialiser tous les champs imbriqués avec les valeurs d'entrée
// TODO: Imprimer le profil de l'employé en utilisant le format :
// Employee: [Name] (ID: [ID])
// Department: [DepartmentName]
// Location: [Building], Floor [Floor]
// Accéder aux champs imbriqués en utilisant la notation par points (ex: employee.Department.Location.Building)
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO en Go
Fichiers externesEspace de travail et Modules GoPackages et ImportsNoms exportés vs non exportésIntroduction à la POO en GoLes Structs comme ClassesDéfinir des méthodes sur les StructsReceveurs par pointeur vs par valeurInitialisation de StructsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL'interface comme contratInterface vide (any)Assertion de typeType SwitchComposition d'interfacesInterfaces Stringer & ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter & SetterMasquage d'informations en GoRécapitulatif - Dossiers étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesContournement pour les méthodes génériquesRécapitulatif - Collections génériques13Patrons de conception, Partie 1
Introduction aux Design PatternsPatron SingletonPatron FactoryPatron Abstract FactoryPatron ObserverPatron Strategy2Exploration approfondie des Types et Structs
Types de base et compositesDéfinitions de types personnalisésTags de StructStructs anonymesStructs imbriquéesValeurs par défaut et Zero ValuesRécapitulatif - Carnet de contacts5Composition plutôt qu'héritage
Pourquoi Go n'a pas d'héritageLes bases de l'imbrication de structsPromotion de méthodesImbriquer plusieurs structsImbrication vs AgrégationMasquage de méthodes imbriquéesRécapitulatif - Hiérarchie des employés8Gestion des erreurs & POO
L'interface errorTypes d'erreurs personnalisésError Wrapping (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - File Parser11Bibliothèque standard et POO
io.Reader & io.WriterL'interface sort.InterfaceL'interface fmt.Stringerencoding/json avec les StructsL'interface http.HandlerRécapitulatif - Modèles d'API REST14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeMiddleware en tant que Décorateur3Pointeurs et Mémoire
Bases des pointeurs en GoPointeurs vers des structsPassage par valeur vs référenceLa fonction new()Garbage Collection en GoRécapitulatif - Constructeur de liste chaînée6Le polymorphisme en Go
Le polymorphisme via les interfacesLe Duck Typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif - Processeur de paiement9Concurrence et POO
Bases des GoroutinesChannels et CommunicationChannels avec buffer vs sans bufferL'instruction Selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures Thread-SafeRécapitulatif - Worker Pool