Init functions
Keep `init` rare, local, and boring; avoid hiding application behavior in package initialization.
Canonical guidance
- use
initsparingly - keep initialization deterministic and cheap
- prefer explicit constructors and startup paths for real application logic
Use when
- package-local registration
- validating static invariants
- computing small derived defaults
Avoid
- reading environment and configuring the whole app in
init - doing I/O in
init - relying on import side effects for ordinary behavior
Preferred pattern
var defaultTimeout = 5 * time.Second
func init() {
if defaultTimeout <= 0 {
panic("invalid default timeout")
}
}
Anti-pattern
- packages that open connections or launch background work as soon as they are imported
Explanation: This anti-pattern is tempting because init runs automatically, but hidden startup logic makes order, testing, and configuration harder to reason about.
Why
- explicit setup is easier to test, override, and debug
Related pages
Sources
- Effective Go - Go Team
- The Go Programming Language Specification - Go Team
- Misusing init functions (#3) - Teiva Harsanyi