Program initialization

December 2, 2024

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)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Happy New Year!

I’ve been on an unannounced, unplanned, month-long hiatus, what with moving my family across the globe. But with the new year starting, and the worst of the chaos behind me, I’m going to try to get back in the saddle again, and pick up where I left off. And what better way to initialize 2025 than with talking about init? Program initialization … Package initialization—variable initialization and the invocation of init functions—happens in a single goroutine, sequentially, one package at a time.


Program execution

Program execution A complete program is created by linking a single, unimported package called the main package with all the packages it imports, transitively. The main package must have package name main and declare a function main that takes no arguments and returns no value. func main() { … } Program execution begins by initializing the program and then invoking the function main in package main. When that function invocation returns, the program exits.


init functions

We’ve been looking at the order of package variable initialization. What if these rules are confusing? Or even non-desterministic for you? Or maybe you simply want to do something more advanced than is feasible in package variable declarations. Is there an alternative? There is! Package initialization … Variables may also be initialized using functions named init declared in the package block, with no arguments and no result parameters. func init() { … } Note that package variables can be initialized, but not declared within an init function.

Get daily content like this in your inbox!

Subscribe