Maison > développement back-end > Golang > Plongez en profondeur dans Go Struct

Plongez en profondeur dans Go Struct

Linda Hamilton
Libérer: 2025-01-04 05:02:40
original
426 Les gens l'ont consulté

Dans Go, struct est un type d'agrégat utilisé pour définir et encapsuler des données. Il permet de combiner des champs de différents types. Les structures peuvent être considérées comme des types de données personnalisés similaires aux classes d'autres langages, mais elles ne prennent pas en charge l'héritage. Les méthodes sont des fonctions associées à un type spécifique (souvent une structure) et peuvent être appelées à l'aide d'une instance de ce type.

Définir et initialiser des structures

Définir une structure

Les structures sont définies à l'aide des mots-clés type et struct. Voici un exemple de définition de structure simple :

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Initialiser une structure

Les structures peuvent être initialisées de différentes manières.

Initialisation avec les noms de champs

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Initialisation avec les valeurs par défaut

Si certains champs ne sont pas spécifiés, ils sont initialisés à leurs valeurs zéro pour les types respectifs.

user2 := User{
  Username: "bob",
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Dans cet exemple, Email sera initialisé à une chaîne vide (""), SignInCount à 0 et IsActive à false.

Initialisation avec un pointeur

Une structure peut également être initialisée à l'aide d'un pointeur.

user3 := &User{
  Username: "charlie",
  Email:    "charlie@example.com",
}
Copier après la connexion
Copier après la connexion

Méthodes et comportement des structures

Dans Go, les structures ne servent pas seulement à stocker des données, mais peuvent également avoir des méthodes définies pour elles. Cela permet aux structures d'encapsuler le comportement lié à leurs données. Vous trouverez ci-dessous une explication détaillée des méthodes et du comportement des structures.

Définir des méthodes pour les structures

Les méthodes sont définies à l'aide d'un récepteur, qui est le premier paramètre de la méthode et spécifie le type auquel appartient la méthode. Le récepteur peut être soit un récepteur de valeur, soit un récepteur de pointeur.

Récepteur de valeur

Un récepteur de valeur crée une copie de la structure lorsque la méthode est appelée, de sorte que les modifications apportées aux champs n'affectent pas la structure d'origine.

type User struct {
  Username string
  Email    string
}

func (u User) PrintInfo() {
  fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email)
}
Copier après la connexion
Copier après la connexion

Récepteur de pointeur

Un récepteur de pointeur permet à la méthode de modifier directement les champs de structure d'origine.

func (u *User) UpdateEmail(newEmail string) {
  u.Email = newEmail
}
Copier après la connexion

Ensembles de méthodes

Dans Go, toutes les méthodes d'une structure forment son ensemble de méthodes. La méthode définie pour un récepteur de valeur inclut toutes les méthodes avec des récepteurs de valeur, tandis que la méthode définie pour un récepteur de pointeur inclut toutes les méthodes avec des récepteurs de pointeur et de valeur.

Interfaces et méthodes structurelles

Les méthodes Struct sont souvent utilisées avec des interfaces pour réaliser le polymorphisme. Lors de la définition d'une interface, vous spécifiez les méthodes qu'une structure doit implémenter.

type UserInfo interface {
  PrintInfo()
}

// User implements the UserInfo interface
func (u User) PrintInfo() {
  fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email)
}

func ShowInfo(ui UserInfo) {
  ui.PrintInfo()
}
Copier après la connexion

Alignement de la mémoire dans les structures

Dans Go, l'alignement de la mémoire pour les structures est conçu pour améliorer l'efficacité de l'accès. Différents types de données ont des exigences d'alignement spécifiques, et le compilateur peut insérer des octets de remplissage entre les champs de structure pour répondre à ces exigences.

Qu’est-ce que l’alignement de la mémoire ?

L'alignement de la mémoire signifie que les données en mémoire doivent être situées à des adresses qui sont des multiples de certaines valeurs. La taille d'un type de données détermine ses exigences d'alignement. Par exemple, int32 nécessite un alignement sur 4 octets et int64 nécessite un alignement sur 8 octets.

Pourquoi l’alignement de la mémoire est-il nécessaire ?

Un accès efficace à la mémoire est essentiel pour les performances du processeur. Si une variable n'est pas correctement alignée, le processeur peut avoir besoin de plusieurs accès à la mémoire pour lire ou écrire des données, entraînant une dégradation des performances. En alignant les données, le compilateur garantit un accès mémoire efficace.

Règles d'alignement de la mémoire structurelle

  • Alignement des champs : l'adresse de chaque champ doit répondre aux exigences d'alignement de son type. Le compilateur peut insérer des octets de remplissage entre les champs pour garantir un bon alignement.
  • Alignement de la structure : la taille d'une structure doit être un multiple de la plus grande exigence d'alignement parmi ses champs.

Exemple :

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Sortie : 12

Analyse :

  • a est un int8, occupant 1 octet, aligné sur 1.
  • b est int32, nécessitant un alignement sur 4 octets. Le compilateur insère 3 octets de remplissage entre a et b pour aligner l'adresse de b sur 4.
  • c est un int8, nécessitant 1 octet, mais la taille totale de la structure doit être un multiple de 4 (la plus grande exigence d'alignement). Le compilateur ajoute 3 octets de remplissage à la fin.

Optimisation de l'alignement de la mémoire

Vous pouvez réorganiser les champs de structure pour minimiser le remplissage et réduire l'utilisation de la mémoire.

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Sortie : 8

Dans cette version optimisée, b est placé en premier, en l'alignant sur 4 octets. a et c sont placés consécutivement, ce qui donne une taille totale de 8 octets, ce qui est plus compact que la version non optimisée.

Résumé

  • Les champs Struct dans Go se voient allouer de la mémoire en fonction de leurs exigences d'alignement, avec des octets de remplissage potentiels.
  • Ajuster l'ordre des champs peut minimiser le remplissage et optimiser l'utilisation de la mémoire.
  • Utilisez unsafe.Sizeof pour déterminer la taille réelle de la mémoire d'une structure.

Structures et composition imbriquées

Dans Go, les structures et la composition imbriquées sont des outils puissants pour la réutilisation du code et l'organisation de données complexes. Les structures imbriquées permettent à une structure d'inclure une autre structure en tant que champ, permettant ainsi la création de modèles de données complexes. La composition, quant à elle, crée de nouvelles structures en incluant d'autres structures, facilitant ainsi la réutilisation du code.

Structures imbriquées

Les structures imbriquées permettent à une structure d'inclure une autre structure en tant que champ. Cela rend les structures de données plus flexibles et organisées. Voici un exemple de structure imbriquée :

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Composition de la structure

La composition permet de combiner plusieurs structures en une nouvelle structure, permettant ainsi la réutilisation du code. En composition, une structure peut inclure plusieurs autres structures en tant que champs. Cela permet de créer des modèles plus complexes et de partager des champs ou des méthodes communs. Voici un exemple de composition de structure :

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Différences entre les structures imbriquées et la composition

  • Structs imbriqués : utilisés pour combiner des structures ensemble, où le type d'un champ dans une structure est une autre structure. Cette approche est souvent utilisée pour décrire des modèles de données avec des relations hiérarchiques.
  • Composition : permet à une structure d'inclure des champs de plusieurs autres structures. Cette méthode est utilisée pour réaliser la réutilisation du code, permettant à une structure d'avoir des comportements et des attributs plus complexes.

Résumé

Les structures et la composition imbriquées sont des fonctionnalités puissantes de Go qui aident à organiser et à gérer des structures de données complexes. Lors de la conception de modèles de données, l'utilisation appropriée de structures et de compositions imbriquées peut rendre votre code plus clair et plus maintenable.

Structure vide

Une structure vide dans Go est une structure sans champs.

Taille et adresse mémoire

Une structure vide occupe zéro octet de mémoire. Cependant, son adresse mémoire peut être égale ou non dans des circonstances différentes. Lorsqu'un échappement de mémoire se produit, les adresses sont égales, pointant vers runtime.zerobase.

user2 := User{
  Username: "bob",
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

À partir de la sortie, les variables a, b et zerobase partagent la même adresse, pointant toutes vers la variable globale runtime.zerobase (runtime/malloc.go).

Concernant les scénarios d'évasion :

  • Les variables c et d s'échappent vers le tas. Leurs adresses sont 0x590d00 et elles sont égales (vrai).
  • Les variables e et f ont des adresses différentes (0xc00008ef47) et se comparent de manière inégale (faux).

Ce comportement est intentionnel dans Go. Lorsque les variables de structure vides ne s'échappent pas, leurs pointeurs sont inégaux. Après s'être échappé, les pointeurs deviennent égaux.

Calcul d'espace lors de l'intégration de structures vides

Une structure vide elle-même n'occupe aucun espace, mais lorsqu'elle est intégrée dans une autre structure, elle peut consommer de l'espace en fonction de sa position :

  • Lorsqu'il s'agit du seul champ de la structure, la structure n'occupe aucun espace.
  • Quand il s'agit du champ premier ou intermédiaire, il n'occupe aucun espace.
  • Lorsqu'il s'agit du dernier champ, il occupe un espace égal au champ précédent.
user3 := &User{
  Username: "charlie",
  Email:    "charlie@example.com",
}
Copier après la connexion
Copier après la connexion

Lorsque les structures vides sont des éléments de tableaux ou de tranches :

type User struct {
  Username string
  Email    string
}

func (u User) PrintInfo() {
  fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email)
}
Copier après la connexion
Copier après la connexion

Applications

La propriété de taille nulle des structures vides leur permet d'être utilisées à diverses fins sans surcharge de mémoire supplémentaire.

Empêcher l'initialisation de structure sans clé

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Implémentation d'une structure de données définie

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Transmission du signal via les canaux

Parfois, le contenu des données transmises via un canal n'est pas pertinent, ne servant que de signal. Par exemple, des structures vides peuvent être utilisées dans les implémentations de sémaphore :

user2 := User{
  Username: "bob",
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous sommes Leapcell, votre premier choix pour déployer des projets Go sur le cloud.

Deep Dive into Go Struct

Leapcell est la plate-forme sans serveur de nouvelle génération pour l'hébergement Web, les tâches asynchrones et Redis :

  1. Support multilingue
  • Développer avec JavaScript, Python, Go ou Rust.
  1. Déployez un nombre illimité de projets gratuitement
  • payez uniquement pour l'utilisation – pas de demande, pas de frais.
  1. Une rentabilité imbattable
  • Payez à l'utilisation sans frais d'inactivité.
  • Exemple : 25 $ prend en charge 6,94 millions de requêtes avec un temps de réponse moyen de 60 ms.
  1. Expérience de développeur simplifiée
  • Interface utilisateur intuitive pour une configuration sans effort.
  • Pipelines CI/CD entièrement automatisés et intégration GitOps.
  • Mesures et journalisation en temps réel pour des informations exploitables.
  1. Évolutivité sans effort et hautes performances
  • Mise à l'échelle automatique pour gérer facilement une concurrence élevée.
  • Zéro frais opérationnels – concentrez-vous uniquement sur la construction.

Explorez-en davantage dans la documentation !

Suivez-nous sur X : @LeapcellHQ


À lire sur notre blog

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal