Я попытался найти точное объяснение того, что init()
функция делает в Go. Я прочитал, что говорит Effective Go, но я не был уверен, полностью ли я понял, что он сказал. Точное предложение, в котором я не уверен, следующее:
И, наконец, означает, наконец, что: init вызывается после того, как все объявления переменных в пакете оценили их инициализаторы, и они оцениваются только после того, как все импортированные пакеты были инициализированы.
Что all the variable declarations in the package have evaluated their initializers
значит? Означает ли это, что если вы объявляете «глобальные» переменные в пакете и его файлах, init () не будет работать до тех пор, пока не будет выполнена вся его оценка, а затем запустит всю функцию init и затем main () при запуске ./main_file_name?
Я также прочитал книгу о путешествиях Марка Саммерфилда:
Если пакет имеет одну или несколько функций init (), они автоматически выполняются перед вызовом функции main () основного пакета.
В моем понимании, init()
это актуально только когда вы запускаете намерены запустить main (), верно? или основной пакет. Кто-нибудь понимает, точнее, не init()
стесняйтесь поправить меня
init()
Я думаю, что это для каждого пакета ... Значит ли это, что если разные файлы имеют свои собственныеinits
, все inint всегда запускаются прямо перед выполнением main ()? Вы также можете уточнить для меня одну вещь, почему у вас есть init () без main и как это работает? Означает ли это, что init () запускается последним до импорта пакета? В противном случае, если его не импортировать и нет главного, программа никогда не выполнится ... верно? (если это не тестовый файл, я думаю ...)main
, например, если вам нужно инициализировать несколько переменных или загрузить некоторые файлы или выполнить однократные вычисления. теперь, если вся ваша программа представляет собой один пакет, который на самом деле не нужен, однако, если это несколько пакетов, некоторым из них может потребоваться выполнить определенную инициализацию для нее.init
- с подключаемой архитектурой, как с Cobra Commander . Обратите внимание, на чтоinit
ссылаются в примерахСмотрите эту картинку. :)
import --> const --> var --> init()
Если пакет импортирует другие пакеты, импортированные пакеты инициализируются первыми.
Инициализируется константа текущего пакета.
Переменные текущего пакета инициализируются тогда.
Наконец,
init()
вызывается функция текущего пакета.источник
Что-то добавить к этому (что я бы добавил как комментарий, но ко времени написания этого поста у меня еще не было достаточно репутации)
Имея несколько блоков в одном пакете, я еще не нашел гарантированного способа узнать, в каком порядке они будут работать. Например у меня есть:
Оба
config.go
иrouter.go
содержатinit()
функции, но при запускеrouter.go
функция запускалась первой (что вызвало мое приложение к панике).Если вы находитесь в ситуации, когда у вас есть несколько файлов, каждый из которых имеет свою собственную
init()
функцию, имейте в виду, что вы не гарантированно получите один перед другим. Лучше использовать присвоение переменной, как показывает OneToOne в своем примере. Лучшая часть: это объявление переменной произойдет до ВСЕХinit()
функций в пакете.Например
config.go:
router.go:
независимо от того,
var ConfigSuccess = configureApplication()
существует ли вrouter.go
илиconfig.go
, он будет запущен до запуска EITHERinit()
.источник
func initialize|loadConfig|connect
отделен отfunc init
, оставляя func init () для базовых вещей (без паники). Это разделение также устраняет необходимость взлома для обеспечения порядка инициализации. Надеюсь быть полезным.init()
вызовов внутри одного пакета определяется тем, как они передаются в компилятор; наgo
заказы инструмента файлы в алфавитном порядке. С этого момента в одном файле они инициализируются в синтаксическом порядке. отредактировано для выбора словаВот еще один пример - https://github.com/alok87/gobyexample/blob/master/init/init.go
Вывод вышеуказанной программы
источник
Возьмем, к примеру, фреймворк или библиотеку, которую вы разрабатываете для других пользователей. Эти пользователи в конечном итоге будут иметь
main function
в своем коде код для запуска своего приложения. Если пользователь напрямую импортирует подпакет проекта вашей библиотеки, тоinit
этот подпакет будет вызван ( один раз ) в первую очередь. То же самое для корневого пакета библиотеки и т.д ...Во многих случаях вы можете захотеть, чтобы блок кода выполнялся без наличия
main func
, напрямую или нет.Если вы, как разработчик мнимой библиотеки, импортируете подпакет вашей библиотеки, который имеет
init
функцию, он будет вызываться первым и один раз , у вас нетmain func
но вам нужно убедиться, что некоторые переменные или таблица, будет инициализирован перед вызовами других функций.Хорошая вещь , чтобы помнить и не беспокоиться о том , что: всегда выполнить один раз для каждого приложения.
init
init
исполнение происходит:init
функцией "вызывающего" пакета,main func
,var = [...] or cost = [...]
,Когда вы импортируете пакет, он будет запускать все свои функции инициализации по порядку .
Я приведу очень хороший пример функции init. Он добавит типы MIME в стандартную библиотеку Go с именем,
mime
а функцияmime
уровня пакета будет напрямую использовать стандартный пакет для получения пользовательских типов MIME, которые уже инициализированы в своейinit
функции:Надеюсь, что это помогло вам и другим пользователям, не стесняйтесь писать снова, если у вас есть еще вопросы!
источник
https://golang.org/ref/mem#tmp_4
источник
init
будет вызываться везде, где используется его пакет (независимо от пустого импорта или импорта), но только один раз.это пакет:
любой пакет (основной пакет или любой тестовый пакет) импортировать как пустой:
или импортируйте его используя func:
инициализация будет входить
0
только один раз. первый пакет, использующий его, его функция init запускается перед инициацией пакета. Так:A вызывает B, B вызывает C, все они имеют функцию init, инициализация C будет выполняться первой перед B, B перед A.
источник
Функция инициализации mutil в одном порядке выполнения пакета:
константный и переменный определенный файл init () выполняет функцию
порядок выполнения функции init по имени файла asc
источник
Сначала запускается функция init, а затем main. Он используется для установки чего-либо до запуска вашей программы, например:
Доступ к шаблону, запуск программы с использованием всех ядер, проверка Goos и арки и т.д ...
источник