init() / main()
Go programs have two special functions: init() and main(). main() is the entry point of the program, while init() is used for package and file initialization. Understanding their execution order is essential for designing Go programs.
Syntax
// main(): the program entry point (main package only)
func main() {
// Program execution starts here.
}
// init(): package initialization function
// Takes no arguments, returns no values, and cannot be called explicitly.
func init() {
// Write package initialization logic here.
}
// Execution order:
// 1. Recursively run init() of all imported packages
// 2. Initialize package-level variables
// 3. Run init() functions in the current package, in definition order
// 4. Run main()
Characteristics of init() / main()
| Function | Description |
|---|---|
| main() | The program entry point, defined only in the main package. Takes no arguments and returns no values. |
| init() | Can be defined in any package, and multiple init() functions can exist in a single file. Cannot be called explicitly. |
| Execution timing | init() runs automatically the first time a package is imported. |
| Multiple init() | A single file can contain multiple init() functions. They are executed in the order they are defined. |
Sample Code
package main
import "fmt"
// Package-level variable. Initialized before init() runs.
var greeting = "Hello"
// init() runs before main().
func init() {
fmt.Println("init() 1: executed")
// Use this for initialization tasks like connecting to a database or loading config.
greeting = greeting + ", Go!"
}
// A single file can contain multiple init() functions.
func init() {
fmt.Println("init() 2: executed")
}
func main() {
fmt.Println("main(): executed")
fmt.Println("Greeting:", greeting)
// Use os.Exit() to control the program's exit code.
// os.Exit(0) for success, os.Exit(1) for failure.
// Note: calling os.Exit() will skip any deferred functions.
}
Notes
init() is useful for tasks that must happen before a package is used, such as loading configuration files, initializing global variables, or establishing database connections. When multiple packages are imported, the Go runtime resolves dependencies and runs each package's init() in the correct order.
Because init() runs implicitly, overusing it can make a program's initialization flow difficult to follow. In many cases, defining an explicit initialization function (e.g., Setup()) and calling it from main() improves transparency. Also, be aware that os.Exit() bypasses deferred functions, so avoid combining the two.
For the basics of functions, see Function Definition / Multiple Return Values. For how packages work, see Packages / import.
If you find any errors or copyright issues, please contact us.