Risposta breve: l'inizializzazione verrà eseguita una sola volta.
Un pacchetto con nessuna importazione viene inizializzata assegnando valori iniziali per tutte le sue variabili a livello di pacchetto e quindi chiamando una funzione a livello di pacchetto con il nome e firma di
func init()
definito nella sua origine. Un identificatore del pacchetto o dell'ambito del file con nome init
può essere dichiarato come una funzione con questa firma. Più di tali funzioni possono essere definite, anche all'interno di un singolo file sorgente; eseguono in ordine non specificato.
All'interno di un pacchetto, le variabili a livello di pacchetto vengono inizializzate e vengono determinati i valori costanti, secondo l'ordine di riferimento: se l'inizializzatore di A dipende da B, A verrà impostato dopo B. L'analisi delle dipendenze non dipende dal valori effettivi degli elementi inizializzati, solo sul loro aspetto nell'origine. A dipende da B se il valore di A contiene una menzione di B, contiene un valore il cui inizializzatore menziona B, o menziona una funzione che menziona B, in modo ricorsivo. È un errore se tali dipendenze formano un ciclo. Se due elementi non sono interdipendenti, verranno inizializzati nell'ordine in cui appaiono nella sorgente, possibilmente in più file, come presentato al compilatore. Poiché l'analisi delle dipendenze viene eseguita per pacchetto, può produrre risultati non specificati se l'inizializzatore di A chiama una funzione definita in un altro pacchetto che fa riferimento a B.
Una funzione init
non può essere riferita da qualsiasi punto di un programma. In particolare, init
non può essere chiamato esplicitamente, né un puntatore a init
essere assegnato a una variabile di funzione.
Se un pacchetto ha importazioni, i pacchetti importati vengono inizializzati prima di inizializzare il pacchetto stesso. Se più pacchetti importano un pacchetto P, P verrà inizializzato solo una volta.
L'importazione di pacchetti, per costruzione, garantisce che non ci possano essere dipendenze cicliche nell'inizializzazione.
Un programma completo viene creato collegando un unico pacchetto non importato denominato pacchetto principale con tutti i pacchetti che importa, in modo transitorio. Il pacchetto principale deve avere il nome del pacchetto main
e dichiarare una funzione main
che non accetta argomenti e non restituisce alcun valore.
func main() { … }
L'esecuzione del programma inizia inizializzando il pacchetto principale e quindi invocando la funzione main
. Quando ritorna la funzione main
, il programma termina. Non aspetta che vengano completate altre goroutine (non principali).
Inizializzazione della variabile-inizializzazione del pacchetto e invocazione delle funzioni init
: avviene in una singola goroutine, in sequenza, un pacchetto alla volta. Una funzione init
può avviare altre goroutine, che possono essere eseguite contemporaneamente al codice di inizializzazione.Tuttavia, l'inizializzazione esegue sempre le sequenze delle funzioni init
: non avvierà il successivo init
finché non viene restituito il precedente.