SoFunction
Updated on 2025-03-03

Detailed explanation of the characteristics and usage of init functions in Go language

1. Introduction

In Go,init()A function is a special function that is automatically executed once when the program starts. Its existence provides us with a mechanism to perform some necessary initialization operations when the program starts, preparing for the normal operation of the program.

In this article, we will discuss it in detailinit()The features, uses and precautions of the function are hoped to help you better understand and use this important Go language feature.

2. Characteristics of init function

2.1 Automatic execution

init()An important feature of a function is that it does not require manual calls, it will be automatically executed when the program starts. When the program starts running, the Go runtime system will automatically call theinit()function. Below is a sample code that demonstratesinit()Features of automatic execution of functions when the program starts:

package main
import "fmt"
func init() {
    ("Init function executed")
}
func main() {
    ("Main function executed")
}

In this example code, we define ainit()Function and onemain()function.init()The function will be executed automatically when the program starts, andmain()The function is the entry function of the program, and willinit()Execute after the function is executed.

When we run this code, the output is as follows:

Init function executed
Main function executed

You can see,init()The function is automatically executed when the program starts andmain()The function was called before. This provesinit()Functions are automatically executed when the program starts and can be used to perform some necessary initialization operations before the program starts.

2.2 Execute after package level variable initialization

When a package is introduced or used, package level constants and variables are initialized first. Then,init()The order in which functions are declared in the code, they are executed automatically. Here is a description of a simple code:

package main
import "fmt"
var (
        Var1 = "Variable 1"
        Var2 = "Variable 2"
)
func init() {
        ("Init function executed")
        ("Var1:", Var1)
        ("Var2:", Var2)
}
func main() {
        ("Main function executed")
}

In this example code, we declare package level constants and ininit()Print their values ​​in the function. existmain()In the function, we print a message. When we run this code, the output is as follows:

Init function executed
Var1: Variable 1
Var2: Variable 2
Main function executed

You can see,init()Functions are automatically executed during the initialization phase of the package and after package level constants and variables are initialized. This verifiesinit()The execution order of the function. Because the initialization of package level constants and variables isinit()The function was executed before it was executed. Therefore, ininit()These constants and variables can be used safely in functions.

2.3 The execution order is uncertain

In a package, if multiple existinit()Functions, their execution order is determined in the order they appear in the code. The first appearanceinit()The function will be executed first and theninit()The function will be executed afterwards.

Specifically, it is defined in the order in the codeinit()The order of functions. If multiple sources are defined in the same source fileinit()Functions, their order will be executed in the order they appear in the source code. The following is an example code to illustrate:

package main
import "fmt"
func init() {
        ("First init function")
}
func init() {
        ("Second init function")
}
func main() {
        ("Main function executed")
}

In this example, we define two in the same packageinit()function. They are executed in the order they appear in the source code。 When we run this code,The output result is:

First init function
Second init function
Main function executed

You can see that the first appearedinit()The function is executed first, then theinit()Execute the function afterward.

But the point is, if multipleinit()Functions are located in different source files respectively, and the order of execution between them is uncertain. This is because the compiler may process these source files in different orders at compile time, resulting ininit()The execution order of functions is uncertain.

To sum up, multiple defined in the same source fileinit()Functions are executed in the order they appear in the code, but in multiple source filesinit()The order of execution of functions is uncertain.

3. Use of init function

3.1 Initialize global variables

In most cases, we can assign initial values ​​directly when defining global variables or constants without usinginit()function to initialize. The way of assigning values ​​directly when defining is more concise and intuitive.

However,Sometimes we may need more complex logic to initialize global variables or constants。 These logics may require runtime calculations、Read configuration files、Perform network requests and other operations,Cannot assign directly when defined。 In this case, we can useinit()Functions to implement these complex initialization logic.

Let's illustrate this with an example. Suppose we have a global variableConfigUsed to store the configuration information of the application, we want to read the configuration from the configuration file and initialize it when the program starts. You can use it nowinit()Functions to implement:

package main
import (
        "fmt"
        "os"
)
var Config map[string]string
func init() {
        Config = loadConfig()
}
func loadConfig() map[string]string {
        // Logic for reading configuration information from configuration file        // This is just an example, which may involve more complex operations in practice        config := make(map[string]string)
        config["key1"] = "value1"
        config["key2"] = "value2"
        return config
}
func main() {
        ("Config:", Config)
        // Other business logic...}

In this example, we define a global variableConfig, and ininit()Called in a functionloadConfig()Functions to read the configuration file and initialize it. existloadConfig()In the function, we simulate the logic of reading configuration information from the configuration file and return a configurationmap

When the program starts,init()The function will be called automatically, perform initialization logic and assign the read configuration information to the global variableConfig. This way, it can be used directly elsewhere in the applicationConfigto obtain configuration information.

useinit()The advantage of functions to initialize global variables or constants is that they can be ensured to be properly initialized during the package initialization phase and can be performed some complex logic, such as reading configuration from files, initializing database connections, etc.

3.2 Perform some necessary verification operations

init()Functions are also commonly used to perform some checking operations to ensure that the program meets specific conditions or requirements before it is run. The purpose of these checking operations is to ensure that the program meets specific conditions before it is officially run, thus avoiding potential problems or errors. Here is a simple example that illustrates the useinit()Necessity for function to perform check operations:

package main
import (
        "fmt"
        "os"
)
var config *Config
func init() {
        err := loadConfig()
        if err != nil {
                ("Failed to load configuration:", err)
                (1)
        }
        err = validateConfig()
        if err != nil {
                ("Invalid configuration:", err)
                (1)
        }
}
func loadConfig() error {
        // Load configuration information from configuration files or environment variables and initialize the config object        // ...
        return nil
}
func validateConfig() error {
        // Verify that the configuration meets specific requirements or constraints        // ...
        return nil
}
func main() {
        // Other operations can be performed here, provided that the configuration is loaded and valid        // ...
}

In this example, we assume that the program needs to load configuration information and verify the configuration. existinit()In the function, we call itloadConfig()The function loads configuration information and callsvalidateConfig()Functions verify the configuration.

If there is an error during configuration loading or verification, we can output the error message and use()The function terminates the program's running. This avoids running the program without meeting the conditions or incorrect configuration, thereby reducing possible problems or errors.

By usinginit()Functions perform checking operations to ensure that the program meets specific conditions before formal operation and handles error conditions in advance, thereby increasing the reliability and maintainability of the program. This reduces the possibility of problems at runtime and improves the readability and maintainability of the code.

4. Notes on the init function

4.1 The init function cannot be called explicitly

When we define ainit()When a function is started, it will be automatically executed when the program is started and cannot be called explicitly. The following is a brief description of this with an example code:

package main
import "fmt"
func init() {
        ("This is the init() function.")
}
func main() {
        ("This is the main() function.")
        // The init() function cannot be called explicitly        // init() // This line of code will cause a compilation error}

In this example, we define ainit()function, and print a message in it. Then, inmain()Print another message in the function. existmain()In the function, we try to call it explicitlyinit()function, but it will cause compilation errors. This is becauseinit()Functions are automatically called when the program starts and cannot be explicitly called in the code.

If we try to callinit()Function, the compiler will report an error, promptundefined: init, because it is not a callable function. Its execution is automatically triggered by the compiler when the program is started and cannot be controlled by function calls.

4.2 The init function is executed only once

init()Functions are executed only once during the application run. It is called when the program starts and is called only once. When a package is imported, theinit()The function will be executed automatically.

At the same time, even if the same package is imported multiple times,init()The function will only be executed once. This is because the Go compiler and runtime system ensure that each package is executed only once throughout the application.init()function. The following is a code to explain:

First, we create autilpackage containing a global variablecounterAnd oneinit()function, it willcounterThe value of 1 is increased.

// 
package util
import "fmt"
var counter int
func init() {
        counter++
        ("init() function in util package executed. Counter:", counter)
}
func GetCounter() int {
        return counter
}

Next, we create two separate packages, respectivelypackage1andpackage2. Both packages will be imported at the same timeutilBag.

// 
package package1
import (
        "fmt"
        "util"
)
func init() {
        ("init() function in package1 executed. Counter:", ())
}
// 
package package2
import (
        "fmt"
        "util"
)
func init() {
        ("init() function in package2 executed. Counter:", ())
}

Finally, we create aprogram, importpackage1andpackage2

// 
package main
import (
        "fmt"
        "package1"
        "package2"
)
func main() {
        ("Main function")
}

Run the above program and we can get the following output:

init() function in util package executed. Counter: 1
init() function in package1 executed. Counter: 1
init() function in package2 executed. Counter: 1
Main function

From the output, it can be seen thatutilIn the packageinit()The function will be executed only once, andpackage1andpackage2ofinit()The same counter value can be obtained in the function. This shows that when multiple packages are imported into another package at the same time,init()The function will be executed only once.

4.3 Avoid executing time-consuming operations in init functions

Wheninit()When performing time-consuming operations in a function, it will affect the startup time of the application. This is becauseinit()Functions are automatically called when the program starts and are executed before other codes are executed. Ifinit()Time-consuming operations in the function will cause the application to start slowly. Here is an example to illustrate this:

package main
import (
        "fmt"
        "time"
)
func init() {
        ("Executing init() function...")
        (3 * ) // Simulation takes time to operate, sleep 3 seconds        ("Init() function execution completed.")
}
func main() {
        ("Executing main() function...")
}

In this example, weinit()Used in functions()The function simulates a time-consuming operation and sleeps for 3 seconds. Then, inmain()A message is output in the function. When we run this program, we will find that there will be a 3-second delay at startup, becauseinit()The time-consuming operation in the function is executed at the start of the program, andmain()The function will be ininit()Execution starts only after the function is executed.

Through this example, we can seeinit()Time-consuming operations in the function will affect the startup time of the application. If it is necessary to perform time-consuming operations, it is best to move them tomain()Functions or other suitable places are executed after the application is started to avoid delays in the startup phase.

In short, in order to maintain the startup performance of the application, you should avoidinit()Time-consuming operations are performed in the function, try to put them when needed before executing to avoid unnecessary startup delays.

5. Summary

This article introduces Go languageinit()Features, uses and precautions of functions.

In the article, we first talk about itinit()The features of the function includeinitThe automatic execution of the function and its execution timing will be explained in detailinit()Several common uses of functions include initializing global variables and performing some necessary verification operations. Then we mentionedinit()Some precautions for functions, such asinitFunctions cannot be called explicitly, etc.

Based on the above content, the correctinit()The introduction of functions is hoped to help you better understand and use this important Go language feature.

The above is a detailed explanation of the characteristics and usage of init functions in Go. For more information about the init functions in Go, please pay attention to my other related articles!