When does the init() function run in GO? [SOLVED]


Written By - Tuan Nguyen
Advertisement

Understanding the init() function in GO

Each Go package can optionally have a private function named init() that is automatically executed at the beginning of execution time—init() runs when the package is initialized at the beginning of program execution. The init() function has the following characteristics:

  • init() takes no arguments.
  • init() returns no values.
  • The init() function is optional.
  • The init() function is called implicitly by Go.
  • You can have an init() function in the main package. In that case, init() is executed before the main() function. In fact, all init() functions are always executed prior to the main() function.
  • A source file can contain multiple init() functions—these are executed in the order of declaration.
  • The init() function or functions of a package are executed only once, even if the package is imported multiple times.
  • Go packages can contain multiple files. Each source file can contain one or more init() functions.

The fact that the init() function is a private function by design means that it cannot be called from outside the package in which it is contained. Additionally, as the user of a package has no control over the init() function, you should think carefully before using an init() function in public packages or changing any global state in init().

 

When should we use init() function?

There are some exceptions where the use of init() makes sense:

  • For initializing network connections that might take time prior to the execution of package functions or methods.
  • For initializing connections to one or more servers prior to the execution of package functions or methods.
  • For creating required files and directories.
  • For checking whether required resources are available or not.

 

Order of execution

This subsection illustrates how Go code is executed. As an example, if a main package imports package A and package A depends on package B, then the following will take place:

  • The process starts with main package.
  • The main package imports package A.
  • Package A imports package B.
  • The global variables, if any, in package B are initialized.
  • The init() function or functions of package B, if they exist, run. This is the first init() function that gets executed.
  • The global variables, if any, in package A are initialized.
  • The init() function or functions of package A, if there are any, run.
  • The global variables in the main package are initialized.
  • The init() function or functions of main package, if they exist, run.
  • The main() function of the main package begins execution.

The following diagram shows what is happening behind the scenes regarding the order of execution of Go code:

When does the init() function run in GO? [SOLVED]

 

Sample init() function

Here is an example of using the init() function in Go:

package main

import "fmt"

var intValue = InitInt()

func InitInt() int {
	return 2022
}

func init() {
	intValue = 10000
}

func main() {
	fmt.Println("init value:", intValue)
}

Output:

init value: 10000

Explanation:

Advertisement
  • It is assumed that the function initInt() will be called before the init()
  • The init() will be invoked before main().
  • Remember that whether or not there is a main function, init() is always called, and if you import a package with an init() method, it will be invoked.

 

Using multiple init() functions

With single package

In this example, we will define many init() functions within a file, and then see the order of functions called:

package main

import (
	"fmt"
)

var intValue = InitInt()

func InitInt() int {
	fmt.Println("This is global variable initialization!")
	return 2022
}

func init() {
	fmt.Println("This is the last init call")
}

func init() {
	fmt.Println("This is the first init call")
}

func init() {
	fmt.Println("This is the second init call")
}

func main() {
	fmt.Println("This is main function!")
}

Output:

This is global variable initialization!
This is the last init call
This is the first init call
This is the second init call
This is main function!

We can see that the global variable initialization will be called first, and they init() functions will be executed in the order they show up in the file.

 

With dependency packages

Each package allows for multiple init() functions, which will be performed in the order they appear in the file (after all variables are initialized).  If they span multiple files, they will be executed in lexical file name order. Here is an example of one package have 2 file: hello1.go and abc.go:

hello1.go

package hello

import "fmt"

var hello1 = HelloFunction1()

func init() {
	fmt.Println("This is init function from hello1.go")
}

func HelloFunction1() bool {
	fmt.Println("Hello1.go file...")
	return true
}

abc.go

package hello

import "fmt"

var testVal = InitFromFuncABC()

func init() {
	fmt.Println("This is init function from abc.go")
}

func InitFromFuncABC() bool {
	fmt.Println("Init from abc.go...")
	return true
}

main.go:

package main

import (
	"fmt"
	_ "hello"
)

func main() {
	fmt.Println("From main function")
}

Output:

Advertisement
Init from abc.go...
Hello1.go file...
This is init function from abc.go
This is init function from hello1.go
From main function

You can see that because we import the hello package; the program will first initialize the global variable and init() function from abc.go, and then initialize the global variable and init() function from hello1.go and finally it will run the main function.

 

Summary

The init() functions will be called:

  • After the package-level variables (global variables, package imports,...).
  • If multiple init() functions, they will be called in the order they show up in the file.
  • Before the main function (optionally).

The init() will be called everywhere uses its package (no matter blank import or import), but only one time. If they span multiple files, they will be executed in lexical file name order.

 

References

https://go.dev/doc/effective_go#init
go - When is the init() function run? - Stack Overflow

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment