2010-06-27 6 views
4

Il semble inutile d'être utilisé dans des constructions de langage primitif, comme vous ne pouvez pas spécifier toute sorte de valeursQuand `new` devrait-il être utilisé dans Go?

func main() { 
    y := new([]float) 
    fmt.Printf("Len = %d", len(*y)) // => Len = 0 
} 

Pour stucts il fait un plus peu sens, mais quelle est la différence entre dire y := new(my_stuct) et la apparemment plus concis y := &my_struct? Et comme tout ce que vous créez est basé sur ces primitives, elles seront initialisées auxdites valeurs nulles. Alors, quel est le point? Quand voudriez-vous utiliser new()?

Désolé pour la question très-débutant, mais la documentation n'est pas toujours aussi claire.

+0

« Quelle est la différence entre ... » 'new' est utilisé sur un type. '&' est utilisé sur une valeur – newacct

Répondre

5

Vous ne pouvez pas utiliser new pour les tranches et les cartes, comme dans votre exemple de code, mais vous devez utiliser le make command: make([]float, 100)

Les deux new(MyStruct) et &MyStruct{} font la même chose, parce que Go attribuera des valeurs sur le tas si vous obtenez leur adresse avec &. Parfois, le code exprime simplement mieux l'intention dans un style ou dans l'autre.

Go n'a pas de prise en charge intégrée pour les constructeurs, donc généralement vous appelez l'appel à new dans une fonction, par exemple NewMyStruct() qui effectue toute l'initialisation nécessaire. Il permet également d'initialiser des champs privés ou de masquer la structure derrière une interface, pour empêcher les utilisateurs de l'objet de jouer directement avec ses internes. Évoluer aussi la structure de la structure est plus facile de cette façon, quand vous n'avez pas besoin de changer tous ses utilisateurs quand vous ajoutez/supprimez/renommez/réorganisez des champs.

+0

En ce qui concerne l'utilisation de nouveau, je suppose que c'est une erreur de compilation qui rend ce code valide et compilable? Ou est-ce que quelque chose d'autre se passe? –

+1

Je suppose que l'appel à nouveau sur des tranches alloue quelque chose, mais ce n'est pas une tranche utilisable. Les tranches et les cartes nécessitent une initialisation spéciale, et l'appel make fait cela. (Je pense que c'est un manque dans la conception du langage qui est nécessaire pour certains types intégrés, mais c'est juste la façon dont il est maintenant.Si des génériques ou des constructeurs sont ajoutés à un moment donné, make ne serait pas nécessaire.) –

+0

voir. Donc je suppose que la réponse est, vous ne le faites pas. –

0

make ne fait que le travail des cartes, des tranches et les canaux et les littéraux composites comme type{} ne fonctionnent que pour les structures, les tableaux, les tranches et les cartes. Pour les autres types, vous devrez utiliser new pour obtenir un pointeur vers une instance nouvellement allouée (si vous ne voulez pas utiliser un var v T; f(&v) plus long).

Je suppose que cela est utile si vous voulez initialiser une struct:

typedef foo struct { 
    bar *int 
} 
v := foo{bar: new(int)}