Quando un'applicazione Go viene avviata, tutti i pacchetti non di test vengono inizializzati in un ordine specifico: prima vengono inizializzate tutte le dipendenze importate (in catena), poi il pacchetto stesso. Per l'inizializzazione vengono utilizzate:
Le funzioni init vengono chiamate dopo l'inizializzazione delle variabili del pacchetto. Se un pacchetto viene importato, il suo init viene eseguito una sola volta prima dell'uso delle variabili/funzioni di quel pacchetto.
Esempio:
var a = getA() func getA() int { fmt.Println("getA chiamato") return 42 } func init() { fmt.Println("init chiamato") } // Stampa: // getA chiamato // init chiamato
Caratteristiche:
È possibile chiamare esplicitamente la funzione init di qualsiasi pacchetto?
Risposta: No, la funzione init non viene mai chiamata direttamente dal codice del programma. Viene chiamata solo dal runtime durante il processo di inizializzazione del pacchetto in un momento predeterminato, la chiamata esplicita di init() non è consentita — porterà a un errore di compilazione.
Storia
Nel progetto, due pacchetti importavano reciprocamente per inizializzare variabili globali tramite init(). Ciò ha portato a dipendenze cicliche e errori durante la compilazione — Go non è riuscito a determinare l'ordine corretto di inizializzazione.
Storia
La causa di un bug complesso è stata che le funzioni init utilizzavano variabili globali del pacchetto che non erano state ancora inizializzate. Risultato: comportamento ambiguo al momento dell'esecuzione con stati non prevedibili.
Storia
Nel progetto, per effetti collaterali è stato importato un pacchetto senza utilizzo esplicito (tramite import _ "some/lib"). Dopo la riorganizzazione del codice, la funzione init del pacchetto necessario veniva chiamata troppo presto (prima dell'inizializzazione delle variabili dipendenti in un altro pacchetto), causando un bug difficile da diagnosticare.