for i := 0; i < 12; i++ {
i := i
...
Tan loco como parece, esto es algo que verá en el código Go. Resulta de la forma en que funcionan los cierres y de la forma en que se definen las variables. Su función anónima es un cierre que captura i. Específicamente, está capturando una variable llamada i, no el valor actual de i, y captura lo que sea que esté en el alcance. En su código original, esta es la variable de bucle, que es la misma variable para cada iteración del bucle. Todos tus cierres capturaron la misma variable. La adición de i := i
declara una nueva variable en cada iteración. Ahora cada cierre capturará esta nueva variable, y en cada iteración será una variable diferente.
Con un poco más de detalle, el alcance de la variable de bucle i es la instrucción for. Esto incluye el bloque de bucle, pero como la declaración de la variable de bucle i está fuera del bloque, declarar una nueva variable con el mismo nombre dentro del bloque es legal y crea una nueva variable en ese punto del bloque. La variable de bucle se sombrea. A menudo, una variable declarada así va a la pila, pero en este caso el análisis de escape del compilador ve que su cierre sigue refiriéndose a esta variable de bloque cuando sale del alcance al final del bloque, por lo que la variable se coloca en el montón. En cada iteración, el bloque vuelve a entrar y una nueva variable i se coloca en el montón.
Respondido en [las Preguntas frecuentes] (http://golang.org/doc/go_faq.html#closures_and_goroutines) también. – kostix