2012-07-08 8 views
15

De mi lectura de la especificación:¿Cuál es la diferencia de alcance de cierre entre declaraciones de variables cortas y largas en Go?

Una breve declaración de variables ... es una forma abreviada de un habitual variables declaración con expresiones de inicializador pero no hay tipos ...

http://golang.org/ref/spec

Hubiera pensado que los dos eran idénticos:

var f func() 
f = func() { 
    ... 
} 

y

f := func() { 
    ... 
} 

Pero parece que no lo son. Yo estaba tratando de envolver una función de auto-recursivo en el interior de una función externa, pero esto funciona:

func myOuter() { 
    var f func() 

    f = func() { 
     f() 
    } 

    f() 
} 

Pero esto no es así, diciendo undefined: f en la función interna.

func myOuter() { 
    f := func() { 
     f() 
    } 

    f() 
} 

¿Cuál es la diferencia? ¿Hay alguna forma de escribir esto con la declaración de forma abreviada o tengo que escribirla a mano larga?

+0

Gracias Kissaki, obviamente pegué la misma cosa dos veces por error. – Joe

Respuesta

14

f := func() { /* ... */ } es idéntico a var f func() = func() { /* ... */ } (pero solo el último está permitido en el nivel del paquete). En su caso específico, ninguna de las dos variantes funcionará, ya que la declaración se evaluará de derecha a izquierda. La solución es, como ya lo ha sugerido, dividir la declaración en dos. Uno para declarar la variable y otro para asignarle la función recursiva.

+1

Gracias! La orden o declaración no se me ocurrió. – Joe

+0

¡Ah! Ahora debo volver a soltar mi código, ¡gracias por esta información! –

0

Los primeros dos ejemplos de código son semánticamente idénticos en una condición: la expresión que se le asigna a la variable debe resolverse en tiempo de compilación.

Esto será idéntico en cada circunstancia, excepto cuando intenta asignar una expresión que hace referencia a la variable (o función) que acaba de declarar. El problema aquí es que debido a que golang se analiza de manera asociativa, intentará escribir resolver la expresión de la derecha antes de asignarla a la izquierda. Si hace referencia a la variable a la izquierda del operador declarar-asignar, está haciendo referencia a una variable que el compilador aún no conoce, de ahí el undefined: f.

Otro ejemplo que produciría resultados similares:

x := x + 1 

Aunque esto es mucho menos común que las personas intentan ya que es más obvio que x aún no se le ha asignado.

Cuestiones relacionadas