Podczas uruchamiania aplikacji Go, wszystkie pakiety non-test są inicjalizowane ściśle w określonej kolejności: najpierw inicjalizowane są wszystkie importowane zależności (w łańcuchu), następnie sam pakiet. Do inicjalizacji używane są:
Funkcje init są wywoływane po inicjalizacji zmiennych pakietu. Jeśli pakiet jest importowany — jego init wykonywana jest raz przed użyciem zmiennych/funkcji tego pakietu.
Przykład:
var a = getA() func getA() int { fmt.Println("getA wywołana") return 42 } func init() { fmt.Println("init wywołana") } // Wyświetli: // getA wywołana // init wywołana
Cechy szczególne:
Czy można jawnie wywołać funkcję init dowolnego pakietu?
Odpowiedź: Nie, funkcja init nigdy nie jest wywoływana bezpośrednio z kodu programu. Jest wywoływana tylko przez runtime podczas procesu inicjalizacji pakietu w z góry określonym momencie, jawne wywołanie init() nie jest dozwolone — doprowadzi to do błędu kompilacji.
Historia
W projekcie dwa pakiety importowały się nawzajem w celu zainicjowania zmiennych globalnych przez init(). Doprowadziło to do cyklicznych zależności i błędów przy kompilacji — Go nie był w stanie określić poprawnej kolejności inicjalizacji.
Historia
Przyczyną skomplikowanego błędu było to, że funkcje init używały globalnych zmiennych pakietu, które jeszcze nie zostały zainicjowane. Wynik: niejednoznaczne zachowanie podczas uruchamiania z nieprzewidywalnymi stanami.
Historia
W projekcie importowano pakiet dla efektów ubocznych bez jawnego użycia (przez import _ "some/lib"). Po reorganizacji kodu funkcja init potrzebnego pakietu była wywoływana zbyt wcześnie (przed inicjalizacją zależnych zmiennych w innym pakiecie), co spowodowało trudny do zdebugowania błąd.