In what order is the init() method invoked in the GO language?

Asked

Viewed 185 times

4

I read some posts on the Internet about the implicit method call init() but I did not understand right in what order it is invoked in a program written in GO language, mainly because there can be several methods init in the same package.

How do I ensure a certain predetermined order ? This is possible ?

2 answers

4

This is a problem that no language I know has been able to solve on its own.

There are no guarantees of the execution order. Simple as that. The compiler even tries to do this within an order that ensures dependencies are met in their fullness but doesn’t count that everything will be done correctly, especially if there are cyclical dependencies.

I have seen languages that provide some resource to facilitate the programmer to manually establish the desired order, but even this can have its problems in certain situations.

The fact of having an automatic or manual guaranteed order does not guarantee that everything will work as expected. And of course an automatic way is harder to reach.

The correct is to write code that does not depend on the boot order. Do not write code in a init() that you need warranties of execution at any given time. The solution when you need explicit assurance is to write explicit calls. Each problem will require a specific solution.

The subject is different but the reading about builders can help understand the difficulty.

Documentation.

4


The GO connection has a very own way of dealing with module initialization/Packages.

There is a description of this boot problem in http://golang.org/doc/effective_go.html#initialization

To simplify see this example showing the implicit and explicit execution in the GO language

Source: main go.

package main

import (
  "fmt"

  cmds "./commands"
  initialization "./init"
)

var isInitialized = initialization.IsApplicationInitialized()

func main() {
  fmt.Printf("•• Invocando o método main\n")
  initialization.Configure()
  // Inicializando a Configuração para os Comandos
  cmds.InitializeCmdConfig()
}

Source: init/init.go

package init

import "fmt"

func IsApplicationInitialized() bool {
  fmt.Printf("•• Invocando o método IsApplicationInitialized\n")
  return true
}

func init() {
  fmt.Printf("•• Invocando o método init de init.go no package init\n")
}

func Configure() {
  fmt.Printf("•• Invocando o método Configure de init.go no package init\n")
}

Outturn:

•• Invocando o método init de init.go no package init
•• Invocando o método init de whatever.go no pacote commands
•• Invocando o método IsApplicationInitialized no package init
•• Invocando o método init em main.go
•• Invocando o método main
•• Invocando o método Configure de init.go no package init
•• Invocando o método InitializeCmdConfig de whatever.go no pacote commands

Below is an explanation.

We can think of the init method as being similar to a static block in a Java class (in this case executed in the load process of the Class by JVM) but we cannot assume anything in relation to the implicit order. The above result was obtained in version 1.4.2 of GO on MAC OSX but there is no guarantee that it will be the same in other versions. You can only guarantee what’s documented.

In this example above the Runtime GO ensures that the method IsApplicationInitialized() run before the method init() existing in main.go and that this method init() will be executed before the method main() at the same source.

The method init() is always called in a given package regardless of whether it exists or not a main, so if we do the import of a package that has a method init this method will be executed, but always after those methods referenced in global scope variable declarations. We may also have multiple methods init() in a given package and they are executed, as already emphasized, after the variables are initialized.

It is healthy that the programmer don’t make any assumptions as to order that these methods are implemented. In case you need a predefined order use the technique shown above when initializing a variable with the call of a method: var isInitialized = initialization.IsApplicationInitialized(). This will force the execution order of a given code before any method init of that package.

Use methods init to initialize value tables for a given API, for example. See an example of using the method init() in bzip2.go source line 480

Browser other questions tagged

You are not signed in. Login or sign up in order to post.