Bases de l’inclusion de structs
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 35 sur 107.
L’intégration de structures est le mécanisme de Go permettant d’inclure un type de structure dans un autre. Au lieu d’utiliser un nom de champ, vous spécifiez simplement le type, et Go rend accessibles les champs de la structure intégrée dans la structure externe.
Voici la syntaxe de base :
type Address struct {
City string
Country string
}
type Person struct {
Name string
Address // embarqué - pas de nom de champ
}
Lorsque vous intégrez Address dans Person, vous pouvez accéder directement aux champs intégrés sur la structure externe :
func main() {
p := Person{
Name: "Alice",
Address: Address{
City: "London",
Country: "UK",
},
}
fmt.Println(p.City) // London - accès direct
fmt.Println(p.Country) // UK - accès direct
fmt.Println(p.Address.City) // fonctionne aussi
}
Remarquez comment p.City fonctionne sans écrire explicitement p.Address.City. Go promeut automatiquement les champs de la structure intégrée, les rendant accessibles comme s’ils appartenaient à la structure externe. Vous pouvez toujours y accéder via le nom du type intégré si nécessaire.
Cela diffère des structures imbriquées ordinaires, dans lesquelles vous devez toujours utiliser le nom du champ pour accéder aux champs internes. L’intégration crée une API plus plate et plus pratique, tout en conservant le regroupement logique des données associées.
Défi
FacileConstruisons un système d'immatriculation de véhicules qui utilise l'intégration de structures pour créer un modèle de données clair et organisé. Vous séparerez les informations de contact des détails du véhicule tout en permettant un accès direct à tous les champs grâce à l'intégration.
Vous organiserez votre code sur deux fichiers :
vehicle.go: Créez deux structures qui fonctionnent ensemble grâce à l'intégration :- Une structure
ContactInfoavec les champsOwnerNameetPhone(tous deux de type chaîne) - Une structure
Vehiclequi intègreContactInfo(sans nom de champ) et ajoute ses propres champsMake,ModeletYear
SummarysurVehiclequi renvoie une chaîne formatée contenant toutes les informations sur le véhicule et le contact.- Une structure
main.go: Lisez les informations du véhicule et du propriétaire depuis l'entrée, créez une instance deVehicleavec unContactInfointégré, et montrez l'accès aux champs intégrés à la fois directement et via le nom du type intégré. Affichez le résumé du véhicule à la fin.
Les entrées suivantes seront fournies :
- Ligne 1 : Nom du propriétaire
- Ligne 2 : Numéro de téléphone
- Ligne 3 : Marque du véhicule
- Ligne 4 : Modèle du véhicule
- Ligne 5 : Année (entier)
Votre méthode Summary doit renvoyer une chaîne dans ce format :
[Year] [Make] [Model] - Owner: [OwnerName], Phone: [Phone]Dans votre fichier principal, montrez la promotion des champs en affichant :
- Le nom du propriétaire accédé directement sur le Vehicle (par exemple,
v.OwnerName) - Le téléphone accédé via le type intégré (par exemple,
v.ContactInfo.Phone) - Le résumé complet de votre méthode
Summary
Par exemple, avec Alice Smith, 555-1234, Toyota, Camry et 2023, votre sortie doit être :
Alice Smith
555-1234
2023 Toyota Camry - Owner: Alice Smith, Phone: 555-1234Remarquez que les deux modes d'accès fonctionnent : l'accès direct grâce à la promotion des champs et l'accès explicite via le nom du type intégré, ce qui vous offre une certaine flexibilité dans la manière de travailler avec les données intégrées.
Essayez vous-même
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Lire le nom du propriétaire
ownerName, _ := reader.ReadString('\n')
ownerName = strings.TrimSpace(ownerName)
// Lire le numéro de téléphone
phone, _ := reader.ReadString('\n')
phone = strings.TrimSpace(phone)
// Lire la marque du véhicule
make, _ := reader.ReadString('\n')
make = strings.TrimSpace(make)
// Lire le modèle du véhicule
model, _ := reader.ReadString('\n')
model = strings.TrimSpace(model)
// Lire l'année
yearStr, _ := reader.ReadString('\n')
yearStr = strings.TrimSpace(yearStr)
year, _ := strconv.Atoi(yearStr)
// TODO: Créer une instance de Vehicle avec ContactInfo embarqué
// Utiliser les valeurs lues depuis l'entrée ci-dessus
// TODO: Afficher le nom du propriétaire accessible directement sur le Vehicle (promotion de champ)
// Exemple: fmt.Println(v.OwnerName)
// TODO: Afficher le téléphone accessible via le nom du type embarqué
// Exemple: fmt.Println(v.ContactInfo.Phone)
// TODO: Afficher le résumé complet en utilisant la méthode Summary
// Exemple : fmt.Println(v.Summary())
// Supprimez ces lignes une fois que vous aurez implémenté la solution
_ = ownerName
_ = phone
_ = make
_ = model
_ = year
}
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 et non exportésIntroduction à la POO en GoStructs comme classesDéfinir des méthodes sur des structsRécepteurs pointeurs ou par valeurInitialisation des structsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL’interface comme contratInterface vide (any)Assertion de typeCommutation de typeComposition d’interfacesInterfaces Stringer et ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter et SetterDissimulation de l’information en GoRécapitulatif – Fiches d’étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesSolution de contournement pour les méthodes génériquesRécapitulatif - Collection générique2Plongée approfondie dans les types et les structs
Types de base et compositesDéfinitions de types personnalisésTags de structStructs anonymesStructs imbriquésValeurs zéro et valeurs par défautRécapitulatif - Carnet de contacts5La composition plutôt que l’héritage
Pourquoi Go n’a pas d’héritageBases de l’inclusion de structsPromotion des méthodesInclure plusieurs structsInclusion ou agrégationMasquage des méthodes inclusesRécapitulatif : hiérarchie des employés8Gestion des erreurs et POO
L’interface errorTypes d’erreurs personnalisésEnrobage des erreurs (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - Analyseur de fichiers11Bibliothèque standard et POO
io.Reader et io.Writersort.InterfaceInterface fmt.Stringerencoding/json avec des structsInterface http.HandlerRécapitulatif - Modèles d’API REST14Modèles de conception – Partie 2
Modèle CommandeModèle AdaptateurModèle DécorateurModèle Méthode modèleModèle ÉtatModèle CompositeMiddleware comme décorateur3Pointeurs et mémoire
Notions de base des pointeurs en GoPointeurs vers des structuresPassage par valeur ou par référenceLa fonction new()Garbage collection en GoRécapitulatif - Constructeur de listes chaînées6Polymorphisme en Go
Polymorphisme via les interfacesDuck typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif – Processeur de paiements9Concurrence et POO
Bases des GoroutinesCanaux et communicationCanaux tamponnés ou non tamponnésInstruction selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures thread-safeRécapitulatif - Pool de workersEntraînez-vous par vous-même : Compilateur Go en ligne