Pourquoi y a-t-il un «nouveau» dans Go?

49

Je suis toujours perplexe quant à pourquoi nous avons newdans Go.

Quand vous voulez instancier une structure, vous faites

t := Thing{}

et vous pouvez obtenir un pointeur sur une nouvelle instance en faisant

t := &Thing{}

Mais il y a aussi cette possibilité:

t := new(Thing)

Ce dernier semble un peu étranger au reste de la langue. &Thing{}est aussi clair et concis que new(Thing)et utilise uniquement les constructions que vous utilisez souvent ailleurs. Il est également plus extensible que vous pourriez le changer en &Thing{3}ou &Thing{Feets:7}.

À mon avis, un mot clé supplémentaire 1 est coûteux, cela rend le langage plus complexe et ajoute à ce que vous devez savoir. Et cela pourrait masquer aux nouveaux arrivants ce qu'il y a derrière l'instanciation d'une structure.

Cela fait aussi un mot réservé.

Alors, quel est le raisonnement derrière new? Est-ce parfois utile? Devrions-nous l'utiliser?


1 : Oui, je sais que ce n'est pas un mot-clé au niveau de la grammaire, vous pouvez l'observer , mais cela ne change rien au fait qu'il s'agisse d'un mot réservé pour le développeur raisonnable.

Denys Séguret
la source
3
"... pour aller codeurs ..." - c'est la raison. F # / Haskell / etc. sont très étrangers aux développeurs C et c’est pourquoi ils obtiennent ~ 0 traction. Scala a fait un effort et maintenant, il est plus accessible et plus connu.
Den
12
Par la même idée, Python et Ruby sont très étrangers aux développeurs C, car ils utilisent des mots-clés inconnus, des règles syntaxiques "étranges" (où sont les accolades?) Et des concepts sémantiques étranges (générateurs? Métaclasses? Décorateurs?). Pourtant, ils ne reçoivent pas ~ 0 traction, bien au contraire.
Xion
8
@Xion: avez-vous examiné le taux de croissance initial de Ruby? Il a fallu des siècles pour arriver là où il est maintenant (18 ans, pour être précis). Python est encore plus vieux (1991!).
Joachim Sauer
2
@AndresF. Une partie de la résistance à la scala n’a rien à voir avec la langue. En tant que jeune programmeur (25 ans), quelque chose dans le nom lui-même me fait penser à un croisement entre un langage basé sur les mathématiques comme Matlab (dont je garde un mauvais souvenir) et un très ancien comme Fortran. Il n'y a jamais eu aucune envie de le regarder.
Izkata
4
Une note de côté: nouveau n'est pas un mot clé dans Go. C'est une fonction intégrée.
Manish Malik

Réponses:

44

La meilleure façon de demander est probablement aux personnes qui y travaillent; exactement ce que j'ai fait !

Tl; dr: il était là à l' origine avant makeet &{}, et il est toujours la fonction à utiliser dans certaines situations.

En gros, voici les parties les plus importantes citées:

Alors, quel est le raisonnement derrière le nouveau? Est-ce quelque chose d'utile? Devrions-nous l'utiliser?

Vous ne pouvez pas faire cela sans nouveau

v := new(int)
*v++
fmt.Println(*v)

new ne fait pas partie des titres de Go, vous ne le trouverez pas souvent, mais vous en aurez besoin quand vous en aurez besoin.

À votre santé

Dave

Après une autre réponse montrant ce genre de solution:

vv := 0
v := &vv
*v++
fmt.Println(*v)

J'ai demandé des précisions supplémentaires:

Donc, fondamentalement, le point de Dave ne tient pas vraiment?

Il y a des endroits où il n'est pas pratique d'insérer une nouvelle variable simplement pour prendre son adresse.

new (T) a une signification immédiate, au lieu d'être un idiome à plusieurs étapes.

Le point de Dave ne tombe que si la simple possibilité technique (de s'en passer new) est convaincante en soi.

N'a-t-on pas discuté de cela parce qu'il était évident que Go devrait l'avoir, car presque toutes les langues l'ont?

Le "doit-on garder new?" la discussion apparaît de temps en temps. Puisque nous ne pouvons pas sortir avant Go 2, si je comprends bien la promesse, il ne semble pas y avoir grand-chose à faire en faisant un tour complet. au moment où Go 2 est pensable, nous pourrions avoir des idées différentes et meilleures ...

Chris

C'est aussi là principalement pour des raisons historiques:

vous devez prendre en compte l'historique du projet. Je pense que le nouveau est introduit avant qu'il y ait make.

C'est vrai. En fait, nous avons lutté pendant un moment avant de proposer l’idée de make. Si vous consultez les journaux du référentiel, vous remarquerez que make n'apparaît qu'en janvier 2009, révision 9a924177598f.

La nouvelle fonction intégrée a également précédé l’idée de & {} pour prendre l’adresse d’un littéral composite (et cette syntaxe est en quelque sorte fausse; elle devrait probablement être (* T) {champs de T} mais il n’y avait pas assez raison de le changer).

La nouvelle fonction n’est pas strictement nécessaire, mais le code semble l’utiliser dans la pratique. Il est difficile de s'en débarrasser à ce stade.

Ian

Florian Margaine
la source
Je serais heureux de voir des liens vers l’autre "doit-on garder le nouveau?" discussions qui apparaissent de temps en temps .
Denys Séguret
Est-ce que quelque chose vous empêche de faire v := &(0)et de sauter la variable temporaire? (Je ne sais pas Go.)
Alex Feinman
3
@AlexFeinman Comme il 0s'agit d'une constante littérale, vous ne pouvez pas prendre son adresse. Un problème peut survenir si vous souhaitez également un type spécifique. C’est pourquoi une syntaxe similaire &intou &int(0)susceptible de s’avérer utile (n’a cependant pas beaucoup réfléchi à la meilleure syntaxe). Mais le faire en deux lignes, comme l'a montré Collins, convient également ( vv := 0; v := &vv).
Denys Séguret
14
"Puisque nous ne pouvons pas sortir jusqu'à Go 2" ... qui, comme tout le monde le sait, ne se produira jamais car Go 2considéré comme dangereux.
Mason Wheeler
2
@MasonWheeler vous m'avez presque tué ... toujours en train de rire de "Go 2 considéré comme dangereux" ... étrangement, je parlais de cet article aujourd'hui au déjeuner.
Daniela Petruzalek le