Ответ
init()
— это специальная функция в Go, которая выполняется автоматически при инициализации пакета, до вызова функции main()
.
Ключевые особенности:
- Автоматический вызов:
init()
вызывается средой выполнения Go, её нельзя вызвать явно. - Порядок выполнения:
- Сначала
init()
вызываются для всех импортируемых пакетов в порядке их импорта. - Затем
init()
вызываются в текущем пакете. Если в одном файле или пакете несколько функцийinit()
, они выполняются в порядке их лексического объявления.
- Сначала
- Нет аргументов и возвращаемых значений: Функция всегда имеет сигнатуру
func init()
. - Множественность: В одном пакете (и даже в одном файле) может быть несколько функций
init()
.
Когда использовать init()
:
Функция init()
полезна для задач, которые нужно выполнить один раз при запуске программы:
- Инициализация глобальных переменных: Например, установка соединения с базой данных.
- Регистрация драйверов: Классический пример — регистрация драйвера базы данных:
import _ "github.com/lib/pq"
. - Проверка конфигурации: Проверка наличия необходимых переменных окружения или конфигурационных файлов.
Пример:
package main
import (
"fmt"
"log"
)
// Глобальная переменная, которая будет инициализирована
var config map[string]string
// Первая init-функция
func init() {
fmt.Println("Первый init: инициализация конфигурации")
config = make(map[string]string)
config["version"] = "1.0"
}
// Вторая init-функция
func init() {
fmt.Println("Второй init: проверка конфигурации")
if config["version"] == "" {
log.Fatal("Версия не установлена!")
}
}
func main() {
fmt.Println("main: приложение запущено")
fmt.Printf("Версия из конфига: %sn", config["version"])
}
Вывод программы:
Первый init: инициализация конфигурации
Второй init: проверка конфигурации
main: приложение запущено
Версия из конфига: 1.0
Когда не стоит использовать init()
:
Несмотря на удобство, init()
следует использовать с осторожностью:
- Скрывает зависимости: Код в
init()
выполняется неявно, что затрудняет понимание и тестирование. - Усложняет тестирование: Тесты могут падать из-за глобального состояния, созданного в
init()
. Лучше использовать явные функции инициализации, которые можно контролировать в тестах. - Обработка ошибок:
init()
не может вернуть ошибку. Единственный способ сообщить о сбое — вызватьpanic()
, что аварийно завершит программу.