web-dev-qa-db-fra.com

Principes de base de Golang et mot-clé new ()

J'apprenais le golang et, en parcourant le chapitre qui décrit les structures, j'ai découvert différentes façons d'initialiser les structures.

p1 := passport{}
var p2 passport
p3 := passport{
    Photo: make([]byte, 0, 0),
    Name: "Scott",
    Surname: "Adam",
    DateOfBirth: "Some time",
}

fmt.Printf("%s\n%s\n%s\n", p1, p2, p3)

Bien que ceux-ci impriment les valeurs des structures

{ } { } { Scott Adam Some time}, le code ci-dessous est imprimé avec une esperluette car il s'agit d'une référence.

pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)

&{ Scott Adam Some time}&{ Anotherscott }

Aidez-moi gentiment avec mes doutes.

  1. dans l'usage pointerp1 := &p3, pointerp1 est la variable de référence à p3, qui contient les données réelles. De même, quelle serait la variable réelle contenant les données pour pointerp2?

  2. Quels seraient les meilleurs scénarios pour utiliser ces différents types d’initialisation?

29
scott

new alloue la mémoire mise à zéro pour un nouvel élément ou tapez ce que vous voulez, puis renvoie un pointeur sur celui-ci. Je ne pense pas que le fait d’utiliser new vs une déclaration de variable courte := type{} c'est surtout la préférence

Pour ce qui est de pointer2, le pointer2 La variable contient ses propres données, quand vous le faites

// initializing a zeroed 'passport in memory'
pointerp2 := new(passport)
// setting the field Name to whatever
pointerp2.Name = "Anotherscott"

new alloue la mémoire mise à zéro en mémoire et renvoie un pointeur sur celle-ci. Bref, new renverra un pointeur sur tout ce que vous créez. C'est pourquoi pointerp2 résultats &{ Anotherscott }

Vous voulez principalement utiliser des pointeurs lorsque vous transmettez une variable que vous devez modifier (mais faites attention aux courses de données utilisant des mutex ou des canaux Si vous avez besoin de lire et d'écrire sur une variable à partir de différentes fonctions)

Une méthode courante que les gens utilisent à la place de new est un type de pointeur:

blah := &passport{}

blah est maintenant un pointeur pour taper passeport

Vous pouvez voir dans ce terrain de jeu:

http://play.golang.org/p/9OuM2Kqncq

Lorsque vous passez un pointeur, vous pouvez modifier la valeur d'origine. Lorsque vous passez un non-pointeur, vous ne pouvez pas le modifier. En effet, les variables in go sont transmises sous forme de copie. Ainsi, dans la fonction iDontTakeAPointer, il reçoit une copie de la structure du testeur, puis modifie le champ de nom, puis le renvoie, ce qui ne fait rien pour nous, car il modifie la copie et non l'original.

43
Datsik
  1. Il y a une variable qui contient encore les données. Vous pouvez déréférencer le pointeur en utilisant *pointerp2, Et même l'assigner à une variable (p2 := pointerp2), Mais cette variable serait une copie des données. C'est-à-dire que la modification de l'un n'affecte plus l'autre ( http://play.golang.org/p/9yRYbyvG8q ).

  2. new a tendance à être moins populaire, surtout en ce qui concerne les structures. Une bonne discussion de son objectif (indice: il est venu en premier) et des cas d’utilisation peuvent être trouvés à l’adresse suivante: https://softwareengineering.stackexchange.com/a/216582 .

Edit: De plus, p1 N’est pas vraiment un type d’initialisation différent de p3, Mais au lieu d’affecter une valeur aux champs de ce type, ils sont initialisés à leur valeur zéro ("" pour string, nil pour []byte). La même chose se produirait pour tous les champs omis:

p4 := passport{
    Name: "Scott",
    Surname: "Adam",
}

Dans ce cas, p4.Photo Et p4.DateOfBirth Auraient toujours une valeur nulle (nil et "" Respectivement). Le cas passport{} En est un où tous les champs sont omis.

3
Igor Dubinskiy

Tout ce que le nouveau mot-clé fait est essentiellement de créer une instance du type souhaité. Cependant, au lieu de renvoyer la déclaration en clair du type, il la référence et renvoie l'adresse de mémoire exacte de ce type dans la pile de processus.

2
Remario