En Go, las variables declaradas sin un inicializador explícito reciben automáticamente lo que se llama valores nulos (zero values), que son diferentes para distintos tipos:
int — 0bool — falsestring — ""Esto es conveniente (sin basura en la memoria), pero puede ser peligroso: para algunos tipos, como slices y mapas, trabajar con valores nil puede llevar a pánicos o errores.
Ejemplo:
var m map[string]int m["key"] = 1 // panic: assignment to entry in nil map var s []int fmt.Println(s, s == nil) // [] true (se pueden agregar elementos, pero no se puede acceder por índice)
¿Cuál es la diferencia entre un valor nil de slice y un valor nil de mapa/canal, y qué errores puede provocar esto?
La respuesta correcta: Un slice con valor nil se puede pasar a funciones, usar con append y range — es seguro, pero trabajar con un mapa nil provocará pánico al intentar escribir (pero la lectura es permitida y devolverá el valor nulo).
Ejemplo:
var m map[string]int fmt.Println(m["no_key"]) // 0 — seguro m["key"] = 1 // panic! var s []int s = append(s, 42) // ok
Historia
Descripción: En un gran proyecto, se utilizaron mapas no inicializados para agregar datos. En la primera escritura, la aplicación fallaba consistentemente con un pánico. El problema se descubrió en producción, cuando se introdujo nueva estadística.
Historia
Descripción: Un servicio serializaba un slice no inicializado, enviándolo como JSON en la respuesta de la API. En lugar de
[], los clientes recibíannull— se tuvo que cambiar el esquema en el frontend para manejar ambas variantes.
Historia
Descripción: En un módulo de caché, se comparaba incorrectamente un mapa nil con un mapa vacío y por ello se determinaba incorrectamente: si había elementos. Esto llevaba a accesos innecesarios a la base de datos, disminuyendo el rendimiento.