Подтвердить что ты не робот

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

Go package A состоит из 3.go файлов, и я использую функции из другого пакета B в каждом файле.

Мне нужно импортировать пакет B в начале каждого из трех файлов, но пакет B фактически инициализирован 3 раза или только 1?

4b9b3361

Ответ 1

Короткий ответ: Инициализация будет выполняться только один раз.

Длинный ответ: укажите соответствующий раздел спецификации - Выполнение программы:

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

func init()

определенный в его источнике. Идентификатор области пакета или идентификатор области с именем init может быть объявлен как функция с этой сигнатурой. Множество таких функций может быть определено даже в пределах одного исходного файла; они выполняются в неуказанном порядке.

В пакете инициализируются переменные уровня пакета, а постоянные значения определяются в соответствии с порядком ссылки: если инициализатор A зависит от B, то A будет задано после B. Анализ зависимости не зависит от фактического значения инициализируемых элементов, только по их появлению в источнике. A зависит от B, если значение A содержит упоминание B, содержит значение, инициализатор которого упоминает B, или упоминает функцию, которая упоминает B, рекурсивно. Это ошибка, если такие зависимости образуют цикл. Если два элемента не являются взаимозависимыми, они будут инициализированы в порядке их появления в источнике, возможно, в нескольких файлах, как представлено компилятору. Поскольку анализ зависимости выполняется для каждого пакета, он может создавать неуказанные результаты, если инициализатор вызывает функцию, определенную в другом пакете, который ссылается на B.

Функция init не может упоминаться нигде в программе. В частности, init нельзя вызывать явно, а также не указывать указатель на init на функциональную переменную.

Если пакет имеет импорт, импортированные пакеты инициализируются перед инициализацией самого пакета. Если несколько пакетов импортируют пакет P, P будет инициализирован только один раз.

Импорт пакетов по конструкции гарантирует, что в инициализации не может быть циклических зависимостей.

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

func main() { … }

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

Инициализация инициализации пакета инициализации и вызов функций init - происходит в одном goroutine, последовательно, по одному пакету за раз. Функция init может запускать другие goroutines, которые могут выполняться одновременно с кодом инициализации. Однако инициализация всегда последовательно выполняет функции init: она не запускает следующий init, пока предыдущий не вернется.