introduction
Construire des abstractions autour de détails concrets est le meilleur outil qu'un langage de programmation peut offrir à un développeur. Les structures permettent aux développeurs de Go de décrire le monde dans lequel un programme Go fonctionne. Au lieu de raisonner sur des chaînes décrivant unStreet
,City
ou unPostalCode
, les structs nous permettent plutôt de parler d'unAddress
. Ils servent de lien naturel pourdocumentation dans nos efforts pour dire aux futurs développeurs (nous y compris) quelles données sont importantes pour nos programmes Go et comment le futur code devrait utiliser ces données de manière appropriée. Les structures peuvent être définies et utilisées de différentes manières. Dans ce tutoriel, nous allons examiner chacune de ces techniques.
Définir des structures
Les structures fonctionnent comme des formulaires papier que vous pourriez utiliser, par exemple, pour déclarer vos impôts. Les formulaires papier peuvent comporter des champs pour des éléments d’information textuels, tels que vos noms de famille. Outre les champs de texte, les formulaires peuvent avoir des cases à cocher pour indiquer des valeurs booléennes telles que «marié» ou «célibataire» ou des champs de date pour la date de naissance. De la même manière, les structures collectent différentes données et les organisent sous différents noms de champs. Lorsque vous initialisez une variable avec une nouvelle structure, c’est comme si vous avez photocopié un formulaire et que vous l’avez préparé à remplir.
Pour créer une nouvelle structure, vous devez d’abord donner à Go un plan détaillé qui décrit les champs qu’elle contient. Cette définition de structure commence généralement par le mot-clétype
suivi du nom de la structure. Après cela, utilisez le mot-cléstruct
suivi d'une paire d'accolades{}
où vous déclarez les champs que la structure contiendra. Une fois que vous avez défini la structure, vous pouvez ensuite déclarer les variables qui utilisent cette définition de structure. Cet exemple définit une structure et l'utilise:
package main
import "fmt"
type Creature struct {
Name string
}
func main() {
c := Creature{
Name: "Sammy the Shark",
}
fmt.Println(c.Name)
}
Lorsque vous exécutez ce code, vous verrez cette sortie:
outputSammy the Shark
Nous définissons d'abord une structureCreature
dans cet exemple, contenant un champName
de typestring
. Dans le corps demain
, nous créons une instance deCreature
en plaçant une paire d'accolades après le nom du type,Creature
, puis en spécifiant les valeurs des champs de cette instance. L'instance dec
aura son champName
défini sur «Sammy the Shark». Dans l’invocation de la fonctionfmt.Println
, nous récupérons les valeurs du champ de l’instance en plaçant un point après la variable dans laquelle l’instance a été créée, suivi du nom du champ auquel nous souhaitons accéder. Par exemple,c.Name
dans ce cas renvoie le champName
.
Lorsque vous déclarez une nouvelle instance d'une structure, vous énumérez généralement les noms de champs avec leurs valeurs, comme dans le dernier exemple. Sinon, si chaque valeur de champ doit être fournie lors de l'instanciation d'une structure, vous pouvez omettre les noms de champs, comme dans cet exemple:
package main
import "fmt"
type Creature struct {
Name string
Type string
}
func main() {
c := Creature{"Sammy", "Shark"}
fmt.Println(c.Name, "the", c.Type)
}
La sortie est la même que celle du dernier exemple:
outputSammy the Shark
Nous avons ajouté un champ supplémentaire àCreature
pour suivre lesType
de créature en tant questring
. Lors de l'instanciation deCreature
dans le corps demain
, nous avons choisi d'utiliser le formulaire d'instanciation plus court en fournissant des valeurs pour chaque champ dans l'ordre et en omettant leurs noms de champ. Dans la déclarationCreature{"Sammy", "Shark"}
, le champName
prend la valeurSammy
et le champType
prend la valeurShark
carName
apparaît en premier dans le déclaration de type, suivie deType
.
Ce formulaire de déclaration abrégé présente quelques inconvénients qui ont amené la communauté Go à préférer le formulaire plus long dans la plupart des cas. Vous devez fournir des valeurs pour chaque champ de la structure lorsque vous utilisez la déclaration courte - vous ne pouvez pas ignorer les champs qui ne vous intéressent pas. Cela provoque rapidement des déclarations courtes pour les structures avec de nombreux champs de créer de la confusion. Pour cette raison, la déclaration de structures à l'aide de la forme courte est généralement utilisée avec des structures comportant peu de champs.
Les noms de champs dans les exemples jusqu’à présent ont tous commencé par des lettres majuscules. Ceci est plus important qu'une préférence stylistique. L'utilisation de lettres majuscules ou minuscules pour les noms de champs détermine si vos noms de champs seront accessibles au code exécuté dans d'autres packages.
Exportation de champs
Les champs d'une structure suivent les mêmes règles d'exportation que les autres identificateurs du langage de programmation Go. Si un nom de champ commence par une lettre majuscule, il sera lisible et inscriptible par un code situé en dehors du paquet où la structure a été définie. Si le champ commence par une lettre minuscule, seul le code du paquet de cette structure sera capable de lire et d’écrire ce champ. Cet exemple définit les champs exportés et ceux qui ne le sont pas:
package main
import "fmt"
type Creature struct {
Name string
Type string
password string
}
func main() {
c := Creature{
Name: "Sammy",
Type: "Shark",
password: "secret",
}
fmt.Println(c.Name, "the", c.Type)
fmt.Println("Password is", c.password)
}
Cela produira:
outputSammy the Shark
Password is secret
Nous avons ajouté un champ supplémentaire à nos exemples précédents,secret
. secret
est un champstring
non exporté, ce qui signifie que tout autre package qui tente d'instancier unCreature
ne pourra pas accéder ou définir son champsecret
. Dans le même package, nous pouvons accéder à ces champs, comme le montre cet exemple. Étant donné quemain
est également dans le packagemain
, il est capable de référencerc.password
et de récupérer la valeur qui y est stockée. Il est courant d’avoir des champs non exportés dans les structures avec un accès via des méthodes exportées.
Structures en ligne
En plus de définir un nouveau type pour représenter une structure, vous pouvez également définir une structure en ligne. Ces définitions de structure à la volée sont utiles dans les situations où inventer de nouveaux noms pour des types de structure serait un effort inutile. Par exemple, les tests utilisent souvent une structure pour définir tous les paramètres qui constituent un cas de test particulier. Il serait fastidieux de trouver de nouveaux noms commeCreatureNamePrintingTestCase
lorsque cette structure est utilisée à un seul endroit.
Les définitions de structure en ligne apparaissent à droite d'une affectation de variable. Vous devez en fournir une instanciation immédiatement après en fournissant une paire d'accolades supplémentaire avec des valeurs pour chacun des champs que vous définissez. L'exemple suivant montre une définition de structure inline:
package main
import "fmt"
func main() {
c := struct {
Name string
Type string
}{
Name: "Sammy",
Type: "Shark",
}
fmt.Println(c.Name, "the", c.Type)
}
La sortie de cet exemple sera:
outputSammy the Shark
Plutôt que de définir un nouveau type décrivant notre structure avec le mot clétype
, cet exemple définit une structure en ligne en plaçant la définition destruct
immédiatement après l'opérateur d'affectation courte,:=
. Nous définissons les champs de la structure comme dans les exemples précédents, mais nous devons alors immédiatement fournir une autre paire d'accolades et les valeurs que chaque champ prendra. L'utilisation de cette structure est maintenant exactement la même qu'auparavant - nous pouvons nous référer aux noms de champs en utilisant la notation par points. L'endroit le plus courant pour afficher les structures en ligne déclarées est lors des tests, car des structures uniques sont souvent définies pour contenir des données et des attentes pour un scénario de test particulier.
Conclusion
Les structures sont des collections de données hétérogènes définies par les programmeurs pour organiser les informations. La plupart des programmes traitent d'énormes volumes de données, et sans structures, il deviendrait difficile de se rappeler quelles variablesstring
ouint
appartenaient ensemble ou lesquelles étaient différentes. La prochaine fois que vous vous retrouverez à jongler avec des groupes de variables, demandez-vous si ces variables seraient peut-être mieux regroupées en utilisant unstruct
. Ces variables ont peut-être toujours décrit un concept de niveau supérieur.