Packages, modules and tooling · 3 MIN READ

init runs before main, and order is defined

Predict the order of package variables, init and main.

A package initializes its variables using their dependency relationships, then runs its init functions in source order as presented to the compiler. Imported packages finish initialization before the importing package. main starts after the program's initialization completes.

Do not depend on arbitrary file presentation order for important behavior. Explicit constructors make configuration and recoverable failure handling visible. An init function takes no arguments and returns no result, though it can register a driver or format as a deliberate import side effect.

SEE THE IDEA

Initialization follows dependencies before main

  1. 01

    Dependencies

    go
    imported packages

    Initialize before their importers

  2. 02

    Package

    go
    variables, then init()

    Prepare package state

  3. 03

    Program

    go
    main.main()

    Runs after initialization completes

Within a package, variable dependency analysis also affects initialization order.

In practice

Prefer explicit constructors when configuration or failure handling belongs to the caller. Init functions take no arguments and return no result, which makes them a poor place for recoverable setup. Several init functions are allowed, but hidden dependence on file presentation order makes maintenance harder.

Watch out

A goroutine started during init may continue running while later initialization proceeds. It needs explicit synchronization if ordering matters.

Official reference ↗

Read and predict

go
package main

import "fmt"

var first = announce("first")
var second = announce("second")

func announce(name string) string {
	fmt.Println("var", name)
	return name
}

func init() {
	fmt.Println("init")
}

func main() {
	fmt.Println("main", first, second)
}

In what order do the lines appear?

Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.