пятница, 8 мая 2020 г.

Инициализация пакета и порядок выполнения программы в Golang

При запуске программы на Go:

  • Сначала инициализируется main пакет.
    • Импортированные пакеты инициализируются до самого пакета.
    • Пакеты инициализируются по одному:
    • первые переменные уровня пакета инициализируются в порядке объявления,
    • затем запускаются init функции.
  • Наконец main функция вызывается.

Выполнение программы

Выполнение программы начинается с инициализации main пакета и последующего вызова функции main. Когда main возвращается, программа выходит. Она не ждет завершения других goroutine.

Инициализация пакета

  • Переменные уровня пакета инициализируются в порядке объявления, но после любой из переменных от которых они зависят.
  • Инициализация переменных, объявленных в нескольких файлах, производится в лексическом порядке имен файлов. Переменные, объявленные в первом файле, объявляются перед любой из переменных, объявленных во втором файле.
  • Циклы инициализации не допускаются.
  • Анализ зависимостей выполняется для каждого пакета; рассматриваются только ссылки на переменные, функции и методы, объявленные в текущем пакете.

Пример

В этом примере, взятом непосредственно из спецификации языка Go, порядок инициализации d, b, c, a.

var (
    a = c + b
    b = f()
    c = f()
    d = 3
)

func f() int {
    d++
    return d
}

Функция init

Переменные также могут быть инициализированы с использованием функций init.

func init() { … }

Несколько таких функций могут быть определены. Их нельзя вызвать изнутри программы.

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

Отсюда следует, что не может быть циклических зависимостей.

Инициализация пакета происходит в одной goroutine, последовательно, по одному пакету за раз.

Предупреждение

Лексическое упорядочение по именам файлов не является частью формальной спецификации языка.

Чтобы обеспечить воспроизводимое поведение при инициализации, системам сборки рекомендуется представлять компилятору несколько файлов, принадлежащих одному и тому же пакету, в лексическом порядке имен файлов.


Читайте также:


Комментариев нет:

Отправить комментарий