2013-07-18 12 views
19

Il pacchetto Go A è composto da 3 file .go e utilizzo le funzioni di un altro pacchetto B in ciascun file.Inizializzazione pacchetto iniziale

Devo importare il pacchetto B all'inizio di ciascuno dei tre file, ma il pacchetto B è effettivamente inizializzato 3 volte o solo 1?

risposta

31

Risposta breve: l'inizializzazione verrà eseguita una sola volta.

Risposta lunga: Citando la relativa sezione specifica - Program execution:

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.