Cuando se inicia una aplicación Go, todos los paquetes que no son de prueba se inicializan estrictamente en un orden específico: primero se inicializan todas las dependencias importadas (en cadena), luego el propio paquete. Para la inicialización se utilizan:
Las funciones init se llaman después de la inicialización de las variables del paquete. Si un paquete se importa, su init se ejecuta una vez antes de usar las variables/funciones de ese paquete.
Ejemplo:
var a = getA() func getA() int { fmt.Println("getA llamado") return 42 } func init() { fmt.Println("init llamado") } // Imprimirá: // getA llamado // init llamado
Particularidades:
¿Se puede llamar explícitamente a la función init de cualquier paquete?
Respuesta: No, la función init nunca se llama directamente desde el código del programa. Se llama solo en tiempo de ejecución durante el proceso de inicialización del paquete en un momento predefinido; la llamada explícita a init() no está permitida y generará un error de compilación.
Historia
En un proyecto, dos paquetes se importaron mutuamente para inicializar variables globales a través de init(). Esto llevó a dependencias cíclicas y errores de compilación, ya que Go no pudo determinar el orden correcto de inicialización.
Historia
La causa de un bug complejo fue que las funciones init utilizaban variables globales del paquete que aún no estaban inicializadas. Resultado: comportamiento ambiguo al ejecutarse con estados impredecibles.
Historia
En un proyecto, se importó un paquete por efectos secundarios sin un uso explícito (a través de import _ "some/lib"). Después de reorganizar el código, la función init del paquete necesario se llamó demasiado pronto (antes de la inicialización de variables dependientes en otro paquete), dando lugar a un bug difícil de depurar.