Go Fundamentals - Sample
Table of Contents
Chapter 5.4: Init
During initialization of a .go
file, the compiler will execute any init
functions it finds in the file before the main function.
Multiple Init Statements
Unlike all other functions, that can only be declared once, the init()
function can be declared multiple times throughout a package or file. However, multiple init()
s can make it difficult to know which one has priority over the others.
When declaring multiple init
functions within the same file the init()
functions will execute in the order that you encounter them. In Listing 5.2 the four init
functions are executed in the order that they are declared in the file.
Init Order
If you have multiple init()
declarations in a package in different files, the compiler will run them based on the order in which it loads files.
Given the directory structure in Listing 5.3, if you had an init()
declaration in a.go
and b.go
, the first init()
to run would be from a.go
. However, if you renamed a.go
to c.go
, the init()
from b.go
would now run first.
Care must be taken if any init()
declarations have an order of precedence when running and exist in different files.
Using init Functions for Side Effects
In Go, it is sometimes required to import a package not for its content, but for the side effects that occur upon importing the package. This often means that there is an init()
statement in the imported code that executes before any of the other code, allowing for the developer to manipulate the state in which their program is starting. This technique is called importing for a side effect.
A common use case for importing for side effects is to register functionality in your code, which lets a package know what part of the code your program needs to use. In the image
package, for example, the image.Decode
function needs to know which format of image it is trying to decode (jpg
, png
, gif
, etc.) before it can execute. You can accomplish this by first importing a specific program that has an init()
statement side effect.
Consider you are trying to use image.Decode
on a .png
file with the function in Listing 5.4.
A program with this code will still compile, but any time we try to decode a png
image, we will get an error.
To fix this, we need to first register the .png
image format for image.Decode
to use. When imported, the image/png
package, which contains the init()
statement in Listing 5.6, will be call and the package will register itself with the image
package as an image format.
In Listing 5.7, we import image.png
package into our application, then the image.RegisterFormat()
function in image/png
will run before any of our code and register the .png
format before we try and use it.
While this use of import
statements and init
functions can be found in numerous places in the standard library, this is considered an anti-pattern in Go and should never be used. Always be explicit in your code.