When a Go application starts, all non-test packages are initialized in a strict order: first, all imported dependencies are initialized (in chain), then the package itself is initialized. The following are used for initialization:
The init functions are called after the package variables are initialized. If a package is imported, its init is executed once before the variables/functions of that package are used.
Example:
var a = getA() func getA() int { fmt.Println("getA called") return 42 } func init() { fmt.Println("init called") } // Output: // getA called // init called
Features:
Can you explicitly call the init function of any package?
Answer: No, the init function is never called directly from the program code. It is called only by the runtime during the package initialization process at a predetermined moment, explicit calls to init() are not allowed — this will result in a compilation error.
Story
In the project, two packages imported each other to initialize global variables via init(). This led to cyclic dependencies and build errors — Go could not determine the correct order of initialization.
Story
A complex bug was caused by init functions using package global variables that had not yet been initialized. The result: ambiguous behavior at runtime with unpredictable states.
Story
In the project, a package was imported for side effects without explicit use (via import _ "some/lib"). After code reorganization, the init function of the required package was called too early (before the dependent variables in another package were initialized), leading to a hard-to-debug bug.