Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is the init() function run?

Tags:

go

init

I've tried to find a precise explanation of what the init() function does in Go. I read what Effective Go says but I was unsure if I understood fully what it said. The exact sentence I am unsure is the following:

And finally means finally: init is called after all the variable declarations in the package have evaluated their initializers, and those are evaluated only after all the imported packages have been initialized.

What does all the variable declarations in the package have evaluated their initializers mean? Does it mean if you declare "global" variables in a package and its files, init() will not run until all of it is evaluated and then it will run all the init function and then main() when ./main_file_name is ran?

I also read Mark Summerfield's go book the following:

If a package has one or more init() functions they are automatically executed before the main package's main() function is called.

In my understanding, init() is only relevant when you intend to run main() right? Anyone understands more precisely init() feel free to correct me

like image 634
Charlie Parker Avatar asked Jul 16 '14 20:07

Charlie Parker


People also ask

Does init run automatically?

If a package has one or more init() functions they are automatically executed before the main package's main() function is called.

What is the init function used for?

The init() function is typically used to initialize a specific state of the application. Although useful, it sometimes makes code difficult to read.

Is INIT called only once?

Init functions are called only once, after all the variable declarations and before the main function. It allows you to initialize whatever your program needs before running.

Can you define multiple init () functions in the same .Go file?

Multiple Init Functions in the Same File At first I didn't think this was possible, but Go does indeed support having 2 separate init() functions within the one file.


2 Answers

Yes assuming you have this:

var WhatIsThe = AnswerToLife()  func AnswerToLife() int { // 1     return 42 }  func init() { // 2     WhatIsThe = 0 }  func main() { // 3     if WhatIsThe == 0 {         fmt.Println("It's all a lie.")     } } 

AnswerToLife() is guaranteed to run before init() is called, and init() is guaranteed to run before main() is called.

Keep in mind that init() is always called, regardless if there's main or not, so if you import a package that has an init function, it will be executed.

Additionally, you can have multiple init() functions per package; they will be executed in the order they show up in the file (after all variables are initialized of course). If they span multiple files, they will be executed in lexical file name order (as pointed out by @benc):

It seems that init() functions are executed in lexical file name order. The Go spec says "build systems are encouraged to present multiple files belonging to the same package in lexical file name order to a compiler". It seems that go build works this way.


A lot of the internal Go packages use init() to initialize tables and such, for example https://github.com/golang/go/blob/883bc6/src/compress/bzip2/bzip2.go#L480

like image 141
OneOfOne Avatar answered Dec 02 '22 11:12

OneOfOne


See this picture. :)

import --> const --> var --> init()

  1. If a package imports other packages, the imported packages are initialized first.

  2. Current package's constant initialized then.

  3. Current package's variables are initialized then.

  4. Finally, init() function of current package is called.

A package can have multiple init functions (either in a single file or distributed across multiple files) and they are called in the order in which they are presented to the compiler.


A package will be initialised only once even if it is imported from multiple packages.

like image 28
weaming Avatar answered Dec 02 '22 12:12

weaming