2012-09-08 14 views
8

Tiene una función con un argumento, un puntero a un tipo.Uso de new vs var en Go

type bar struct{...} 

func foo(arg *bar) 

¿Hay alguna diferencia entre:

var b bar 
foo(&b) 

y

b := new(bar) 
foo(b) 

El uso de la nueva crea una asignación.

+2

No lo creo. Esta pregunta específicamente pregunta sobre el resultado de '& Variable' vs' new (Type) 'cuando se pasa a una función de toma de tipo de puntero. 10990174 no pregunta ni responde eso. – zzzz

Respuesta

10

No, no hay ninguna diferencia, ya que, a diferencia de C, pasar de forma explícita que se puede dar un puntero a una variable creada localmente.

De the documentation:

Tenga en cuenta que, a diferencia de C, es perfectamente correcto para devolver la dirección de una variable local ; el almacenamiento asociado con la variable sobrevive después de que la función devuelve

4

Ambos deberían representar el mismo puntero al mismo objeto inicializado con el mismo valor predeterminado.

El spec menciona:

Después

type T struct { i int; f float64; next *T } 
t := new(T) 

se cumple lo siguiente:

t.i == 0 
t.f == 0.0 
t.next == nil 

Lo mismo también es verdad después

var t T 

También:

Tomando la dirección de un literal compuesto (§ Address operators) genera un puntero a una instancia única del valor de la literal.

var pointer *Point3D = &Point3D{y: 1000} 
-3

Existen ciertas diferencias en ciertas situaciones. new(T), como su nombre lo indica, devuelve una, bien, nueva instancia de tipo T, mientras que var b T es una sola instancia, una vez y para siempre (err, en realidad hasta el final de su vida == fuera del alcance, no alcanzable ...) .

consideran este bucle

var b bar 
for i := 0; i < 10; i++ { 
    foo(&b) 
} 

vs

var b *bar 
for i := 0; i < 10; i++ { 
    b = new(b) 
    foo(b) 
} 

En el último caso, si foo por ejemplo almacena su arg en algún recipiente, los resultados en 10 casos de bar existente mientras el primer caso con solo uno - en la variable b.

Otra diferencia está en el rendimiento. La variable b sería una variable global totalmente estática o, por lo general, se ubicará en un desplazamiento estáticamente conocido en algún registro de invocación de función/método (un nombre elegante para generalmente un marco de pila). new OTOH, si no está optimizado por el compilador, es una llamada al asignador de memoria. Dicha llamada costará un tiempo no nulo. Si se realiza en un bucle y no es realmente necesario, puede provocar una desaceleración notable de alguna ruta de código.

+1

La única diferencia es que new() devuelve un puntero a una variable mientras que var le permite declarar una variable. Esta respuesta tendría sentido si Go reconociera la diferencia entre stack y heap en el lenguaje. Ver la respuesta de dystroy a continuación y mi propia respuesta a otra pregunta http://stackoverflow.com/a/10990287/727643 –

+5

Esta es la respuesta es incorrecta. –

+0

@StephenWeinberg: Respuardo mi respuesta. (Por supuesto, después de que ahora lo comprobé dos veces). Por favor especifique las fallas percibidas por las especificaciones. Además, dígame qué alternativa (razonable) a la asignación de memoria es la implementación de 'new'. Además, avíseme qué compilador Go utiliza esa alternativa. Gracias por adelantado. Me doy cuenta de que las especificaciones no hablan de pila o montón. Eso no excluye hablar sobre cómo funciona la implementación, especialmente si ayuda a la comprensión. Ver también: http://research.swtch.com/godata – zzzz