¿Por qué hay un "nuevo" en Go?

49

Todavía estoy desconcertado de por qué tenemos newen Go.

Cuando quieres crear una instancia de una estructura, lo haces

t := Thing{}

y puede obtener un puntero a una nueva instancia haciendo

t := &Thing{}

Pero también existe esta posibilidad:

t := new(Thing)

Este último parece un poco ajeno al resto del lenguaje. &Thing{}es tan claro y conciso como new(Thing)y solo utiliza construcciones que a menudo usa en otros lugares. También es más extensible, ya que podría cambiarlo a &Thing{3}o &Thing{Feets:7}.

En mi opinión, tener una palabra clave complementaria 1 es costoso, hace que el lenguaje sea más complejo y se suma a lo que debe saber. Y podría enmascarar a los recién llegados lo que hay detrás de crear instancias de una estructura.

También hace una palabra más reservada.

Entonces, ¿cuál es el razonamiento detrás new? ¿A veces es útil? ¿Deberíamos usarlo?


1 : Sí, sé que no es una palabra clave en el nivel de gramática, puede ocultarla , pero eso no cambia el hecho de que es, para el desarrollador razonable, una palabra reservada.

Denys Séguret
fuente
3
"... para ir codificadores ..." - esta es la razón. F # / Haskell / etc. son muy ajenos a los desarrolladores de C y es por eso que están obteniendo ~ 0 de tracción. Scala hizo un esfuerzo y ahora es más accesible y más conocido.
Den
12
Por la misma noción, Python y Ruby son muy ajenos a los desarrolladores de C, ya que usan un montón de palabras clave desconocidas, reglas sintácticas "extrañas" (¿dónde están los corchetes?) Y conceptos semánticos extraños (generadores, metaclases, decoradores?). Sin embargo, no obtienen tracción ~ 0, todo lo contrario.
Xion
8
@ Xion: ¿miraste la tasa de crecimiento inicial de Ruby? Se necesitaron años para llegar a donde está ahora (18 años, para ser precisos). Python es aún más viejo (¡1991!).
Joachim Sauer
2
@AndresF. Parte de la resistencia a Scala podría no tener nada que ver con el idioma. Como programador más joven (25 años), algo sobre el nombre en sí mismo me hace pensar en un cruce entre un lenguaje matemático como Matlab (del cual tengo malos recuerdos) y uno realmente antiguo como Fortran. Nunca ha habido ningún impulso de siquiera mirarlo.
Izkata
44
Una nota al margen: nuevo no es una palabra clave en Go. Es una función incorporada.
Manish Malik

Respuestas:

44

La mejor manera de preguntar es probablemente a las personas que trabajan en él; ¡exactamente lo que hice !

Tl; dr: originalmente estaba allí antes makey &{}todavía es la función para usar en algunas situaciones.

Básicamente, aquí están las partes más importantes citadas:

Entonces, ¿cuál es el razonamiento detrás de lo nuevo? ¿Es algo útil? ¿Deberíamos usarlo?

No puedes hacer esto sin novedades

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

nuevo no es una característica principal de Go, no lo encontrarás usado a menudo, pero cuando lo necesites, está ahí.

Salud

Dave

Después de otra respuesta que muestra este tipo de solución:

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

Pedí más aclaraciones:

Entonces, básicamente, ¿el punto de Dave realmente no es válido?

Hay lugares donde es inconveniente introducir una nueva variable solo para tomar su dirección.

nuevo (T) tiene un significado directo e inmediato, en lugar de ser un modismo de varios pasos.

El punto de Dave solo cae si la mera posibilidad técnica (de prescindir new) es convincente por sí sola.

¿No se discutió esto porque era obvio que Go debería tenerlo porque casi todos los idiomas lo tienen?

El "¿nos quedaremos new?" De vez en cuando surge una discusión. Dado que no podemos eliminarlo hasta el Go 2, si entiendo la Promesa correctamente, no parece que haya mucho que recorrer de nuevo; para cuando Go 2 sea pensable, podríamos tener algunas ideas diferentes y mejores ...

Chris

También está allí principalmente por razones históricas:

debes considerar la historia del proyecto. Creo que lo nuevo se introduce primero antes de que haya una marca.

Eso es verdad. De hecho, luchamos por un tiempo antes de tener la idea de hacer. Si observa los registros del repositorio, puede ver que make solo aparece en enero de 2009, revisión 9a924177598f.

La nueva función incorporada también precedió a la idea de & {} para tomar la dirección de un literal compuesto (y esa sintaxis es en cierto sentido incorrecta; probablemente debería ser (* T) {campos de T} pero no había suficiente razón para cambiarlo).

La nueva función no es estrictamente necesaria, pero el código parece usarla en la práctica. Es difícil deshacerse de él en este momento.

Ian

Florian Margaine
fuente
Me encantaría ver enlaces a los otros "¿mantendremos nuevos?" discusiones que aparecen de vez en cuando .
Denys Séguret
¿Algo le impide hacer v := &(0)y omitir la variable temporal? (No sé ir.)
Alex Feinman
3
@AlexFeinman Como 0es una constante literal, no puede tomar su dirección. Se produciría un problema si desea un tipo específico también. Es por eso que una sintaxis gusta &into &int(0)podría ser útil (sin embargo, no pensé mucho en la mejor sintaxis). Pero hacerlo en dos líneas como Collins mostró también está bien ( vv := 0; v := &vv).
Denys Séguret
14
"Dado que no podemos sacarlo hasta Go 2" ... lo cual, como todos saben, nunca sucederá porque Go 2se considera dañino.
Mason Wheeler
2
@MasonWheeler casi me matas ... aún riéndome de "Go 2 considerado dañino" ... curiosamente, hoy estaba hablando de ese artículo en el almuerzo.
Daniela Petruzalek