func init() {}

Stefan Alfbo - Mar 4 - - Dev Community

If you are coming from other languages that are OOP based like C#, then you might wonder what tool you can use in Go to do something similar as the constructor in a class.

The solution to this is the init function. This is a function that can be defined in each source file.

func init() {
   // initialization code
}
Enter fullscreen mode Exit fullscreen mode

The function signature tells us that it neither takes any parameters or returns any result, which hints us that it is supposed to produce some kind of side effect. It's is not uncommon to see the expression, importing a side effect, which refers to this. From the The Go Programming Language Specification:

To import a package solely for its side-effects (initialization), use the blank identifier as explicit package name:

import _ "lib/math"

So this function is the home for initializing variables to get a program to its correct state before everything is starting to run.

Lets do some examples.

package main

import "fmt"

var message = "Hello, init"

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

func main() {
    fmt.Println("main")
}
Enter fullscreen mode Exit fullscreen mode

This program will produce the following output:

output from first example

That's pretty straightforward. First the variable message will be declared and then the init function will be called, and finally the main function.

It is also possible to define several init functions in the same source file.

package main

import "fmt"

var first = "Hello, init"
var second = "Hello, again init"

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

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

func init() {
    fmt.Println(second)
}
Enter fullscreen mode Exit fullscreen mode

Which product the following output:

output from second example

The init functions will be executed in the order they are defined in the source file. Note that I moved both init functions after the main function to just show that they still will be executed before the main function.

So what happens if you have several source files in the same package that is using an init function?

// first.go
package main

import "fmt"

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

// main.go
package main

import "fmt"

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

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

// z.go
package main

import "fmt"

func init() {
    fmt.Println("z.go")
}
Enter fullscreen mode Exit fullscreen mode

The it will execute the init functions based on lexical order of the filenames. Therefore the init in first.go will be executed first, then the one in main.go and finally the one in z.go.

output last example

If you browse through the code in the standard packages you will find many cases where the init function has been used. However be careful, side effects can make things harder to understand when reading the code.

Happy hacking!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .