Wenn eine Go-Anwendung gestartet wird, werden alle non-test-Pakete strikt in einer bestimmten Reihenfolge initialisiert: Zuerst werden alle importierten Abhängigkeiten (kettende Weise) initialisiert, dann das Paket selbst. Für die Initialisierung werden verwendet:
Die init-Funktionen werden nach der Initialisierung der Paketvariablen aufgerufen. Wenn ein Paket importiert wird, wird dessen init einmal vor der Verwendung der Variablen/Funktionen dieses Pakets ausgeführt.
Beispiel:
var a = getA() func getA() int { fmt.Println("getA aufgerufen") return 42 } func init() { fmt.Println("init aufgerufen") } // Gibt aus: // getA aufgerufen // init aufgerufen
Besonderheiten:
Kann man die init-Funktion eines beliebigen Pakets ausdrücklich aufrufen?
Antwort: Nein, die init-Funktion wird niemals direkt aus dem Programmcode aufgerufen. Sie wird nur zur Laufzeit während des Initialisierungsprozesses des Pakets zu einem vordefinierten Zeitpunkt aufgerufen, ein direkter Aufruf von init() ist nicht zulässig — dies führt zu einem Kompilierungsfehler.
Geschichte
Im Projekt hatten zwei Pakete wechselseitige Imports, um globale Variablen über init() zu initialisieren. Dies führte zu zyklischen Abhängigkeiten und Fehlern beim Kompilieren — Go konnte die korrekte Reihenfolge der Initialisierung nicht bestimmen.
Geschichte
Ursache eines komplexen Fehlers war, dass die init-Funktionen globale Paketvariablen verwendeten, die noch nicht initialisiert waren. Ergebnis: Mehrdeutiges Verhalten beim Start mit unvorhersehbaren Zuständen.
Geschichte
Im Projekt wurde ein Paket für Nebeneffekte importiert, ohne es ausdrücklich zu verwenden (über import _ "some/lib"). Nach der Umstrukturierung des Codes wurde die init-Funktion des benötigten Pakets zu früh aufgerufen (vor der Initialisierung der abhängigen Variablen in einem anderen Paket), was einen schwer zu debuggenden Fehler verursachte.