Порядок инициализации пакета

Порядок инициализации пакета в Go определяет, в какой последовательности выполняются инициализация переменных уровня пакета и вызов функций init. Инициализация происходит в следующем порядке: сначала инициализируются все переменные пакета в порядке их объявления, затем выполняются функции init в порядке их объявления, и только после этого выполняется функция main.

Синтаксис

Функция init не имеет параметров и не возвращает значений. Она может быть объявлена в любом количестве внутри пакета:

gofunc init() {
  // код инициализации
}

Пример

Давайте рассмотрим порядок инициализации переменных и функций init:

gopackage main

import "fmt"

var a = "a"
var b = "b"

func init() {
  fmt.Println("init 1")
}

func init() {
  fmt.Println("init 2")
}

func main() {
  fmt.Println("main")
  fmt.Println(a, b)
}

Результат выполнения кода:

go"init 1"
"init 2"
"main"
"a b"

Пример

Инициализация переменных может зависеть от других переменных, объявленных ранее в том же пакете:

gopackage main

import "fmt"

var x = 5
var y = x * 2
var z = y + 10

func init() {
  fmt.Println("x:", x, "y:", y, "z:", z)
}

func main() {
  fmt.Println("values are initialized")
}

Результат выполнения кода:

go"x: 5 y: 10 z: 20"
"values are initialized"

Переменная y инициализируется значением x, умноженным на 2, а переменная z — суммой y и 10. Это работает, потому что переменные инициализируются в порядке их объявления.

Пример

При импорте пакетов сначала инициализируются импортируемые пакеты, затем текущий пакет:

gopackage main

import "fmt"

var result = getResult()

func getResult() string {
  fmt.Println("variable initialization")
  return "initialized"
}

func init() {
  fmt.Println("init function")
}

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

Результат выполнения кода:

go"variable initialization"
"init function"
"initialized"

Сначала инициализируется переменная result, затем вызывается функция init, и только потом выполняется main.

Смотрите также

  • статью Функция init,
    которая подробно описывает назначение функции инициализации
  • статью Пакет main,
    которая описывает точку входа в программу
  • статью Область видимости пакета,
    которая описывает переменные уровня пакета
  • статью Циклический импорт,
    которая описывает проблемы с инициализацией при циклических зависимостях