I wasn’t exactly planning to take last week off from the daily emails, but with Thanksgiving preparations, and still living out of a suitcase, it just happened that way.
But I’m back now, and ready to talk about Program initialization
Program initialization
The packages of a complete program are initialized stepwise, one package at a time. If a package has imports, the imported packages are initialized before initializing the package itself. If multiple packages import a package, the imported package will be initialized only once. The importing of packages, by construction, guarantees that there can be no cyclic initialization dependencies. More precisely:
Given the list of all packages, sorted by import path, in each step the first uninitialized package in the list for which all imported packages (if any) are already initialized is initialized. This step is repeated until all packages are initialized.
Let’s step through a simple example to illustrate.
Suppose a complete program is made up of main.go
with the following imports:
package main
import (
"bar"
"foo"
)
and foo/foo.go
with no imports, and bar/bar.go
the following imports:
package bar
import (
"foo"
)
Initialization will first look at the list of imports for the main package: bar
and foo
. But it cannot yet initialize bar
, because it in turn has uninitialized imports: foo
. So the program initialization moves on to initialize foo
, which succeeds immediately, beaues foo
has no imports of its own.
Then the initiailization of bar
can succeed, because all of its imports are now initialized.
We then move back up to main
again, as bar
has been initialized. We then see that foo
is next in the list, but it was already initialized, and we only initialize each import once. So program initialization is complete.
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)