Go packages can have more than one init() function

October 15, 2020

Go has some surprisingly complex rules for how packages are initialized, partly because package level variables can be initialized based on the value returned from function and method calls (and then other variables can be initialized from them). As part of package initialization, you can have an initialization function, called init(), that will be called.

Or at least that's what I would have told you before I actually had a reason to read that section of the Go language specification today. In fact, the specification is very clear that you can have more than one init() function in a single package:

Variables may also be initialized using functions named init declared in the package block, with no arguments and no result parameters.

func init() { … }

Multiple such functions may be defined per package, even within a single source file. [...]

(Emphasis mine. Package initialization then has details on what order these init functions are run in.)

At first this surprised me, but once I thought more it makes sense. On a practical engineering level, it means that you don't have to jam all initialization in a package into a single function in a single file that everyone has to touch; you can spread it out in small pieces wherever is logical and clear.

(You do have to keep track of it all, and the order that functions in different files get run in depends on how they're built and linked. The Package initialization section has some suggestions about that down at the bottom, which you probably don't have to worry about if you build things with plain usage of go since it should do it right for you.)

Because I was curious, I scanned the Go source tree itself to see if anything used multiple init functions, especially in the same file. There is definitely a decent amount of usage of this within the same package, and even a few cases in the same file (for example, in cmd/go/main.go). Unsurprisingly, the runtime package is a big user of this, since it covers a lot of functionality; a lot of files in src/runtime have their own init functions to cover their specific concerns.

(However the champion user of init functions is cmd/compile/internal/ssa/gen.)

Written on 15 October 2020.
« As an outsider, I prefer issue tracking to be in its own application
Go is gaining the ability to trace init calls on program startup »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Oct 15 00:07:32 2020
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.