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.
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 }
Les structures peuvent être initialisées de différentes manières.
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
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", }
Dans cet exemple, Email sera initialisé à une chaîne vide (""), SignInCount à 0 et IsActive à false.
Une structure peut également être initialisée à l'aide d'un pointeur.
user3 := &User{ Username: "charlie", Email: "charlie@example.com", }
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.
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.
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) }
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 }
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.
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() }
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.
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.
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.
Exemple :
type User struct { Username string Email string SignInCount int IsActive bool }
Sortie : 12
Analyse :
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, }
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.
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.
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 }
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, }
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.
Une structure vide dans Go est une structure sans champs.
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", }
À 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 :
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.
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 :
user3 := &User{ Username: "charlie", Email: "charlie@example.com", }
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) }
La propriété de taille nulle des structures vides leur permet d'être utilisées à diverses fins sans surcharge de mémoire supplémentaire.
type User struct { Username string Email string SignInCount int IsActive bool }
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
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", }
Nous sommes Leapcell, votre premier choix pour déployer des projets Go sur le cloud.
Leapcell est la plate-forme sans serveur de nouvelle génération pour l'hébergement Web, les tâches asynchrones et Redis :
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!