Go wspiera funkcję init do wykonywania kodu inicjalizacyjnego przed rozpoczęciem main(). Przy uruchamianiu programu kompilator Go automatycznie wywołuje wszystkie funkcje init zadeklarowane w każdym pakiecie po inicjalizacji zmiennych pakietu.
Historia pytania: potrzeba jednorazowego przygotowania stanu pakietu przed jego użyciem.
Problem: kolejność inicjalizacji init często staje się przyczyną niejawnych błędów: trudno kontrolować, kiedy dokładnie zadziała konkretna funkcja init, szczególnie przy wielu zależnościach między pakietami.
Rozwiązanie:
Przykład kodu:
package example import "fmt" var Cfg string = "default" func init() { fmt.Println("example init") Cfg = "configured" }
Kluczowe cechy:
Czy można zdefiniować więcej niż jedną funkcję init w jednym pliku?
Tak, dozwolone są wielokrotne funkcje init — będą wywoływane w kolejności ich deklaracji.
Co się stanie, jeśli pakiet jest importowany tylko pośrednio (przez _ "package")?
Wykonają się tylko funkcje init i inicjalizacja zmiennych tego pakietu.
Czy funkcje init mogą zwracać wartość lub błąd?
Nie. Sygnatura init jest niezmienna: func init(), bez parametrów i wartości zwracanych.
Duży projekt polegał na skomplikowanych funkcjach init, które inicjalizowały globalne stany z zależnościami między pakietami. Powodowało to pływające błędy uruchamiania.
Zalety:
Wady:
Init jest używany tylko do podstawowych lub specyficznych zadań testowych, reszta jest realizowana w jawnych funkcjach wywoływanych z main(). Kolejność uruchamiania jest oczywista, co upraszcza testowanie.
Zalety:
Wady: