Функция `init`
Часть раздела Логика и управление потоком путешествия по GO на Coddy — урок 56 из 68.
Функция init — это специальная функция в Go, которая запускается автоматически при импорте пакета. В отличие от обычных функций, вы не вызываете init напрямую — Go выполняет её за вас в процессе инициализации пакета.
Вот как определяется функция init:
package mypackage
import "fmt"
func init() {
fmt.Println("Package mypackage is being initialized!")
}Функция init обладает некоторыми уникальными характеристиками: она не принимает параметров, не возвращает значений и запускается до начала выполнения функции main. Это делает её идеальной для настройки начального состояния, регистрации компонентов или выполнения разовых задач по настройке, необходимых вашему пакету.
Когда вы импортируете пакет, содержащий функцию init, вы сразу увидите результаты её работы, даже если вы не используете ни одну из экспортируемых функций пакета. Вот почему паттерн импорта с использованием пустого идентификатора, который вы изучили ранее, так полезен — он позволяет запустить инициализацию пакета без прямого использования его кода.
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Задание
ЛегкоСоздайте систему инициализации пакетов, которая демонстрирует, как функции init выполняются автоматически при импорте пакетов. Вы создадите систему логирования, в которой различные пакеты инициализируют себя и отслеживают последовательность своего запуска.
Вы получите два входных значения:
- Строка, содержащая определения пакетов в формате
"package1:message1,package2:message2,package3:message3"(например,"database:Database connection pool initialized,cache:Cache system ready,logger:Logging system started") - Строка, содержащая основные операции программы в формате
"operation1,operation2,operation3"(например,"start_server,process_requests,shutdown")
Ваша задача:
- Разобрать первый входной параметр, разделив его по запятым, чтобы получить определения отдельных пакетов
- Для каждого определения пакета разделить его по двоеточию, чтобы получить имя пакета и сообщение об инициализации
- Создать глобальный срез (slice) с именем
initLogдля отслеживания сообщений об инициализации - Создать функцию с именем
logInit, которая принимает имя пакета и сообщение, а затем добавляет отформатированное сообщение"[INIT] [package_name]: [message]"в срезinitLog - Симитировать инициализацию пакетов, вызывая
logInitдля каждого пакета в том порядке, в котором они появляются во входных данных - Вывести заголовок последовательности инициализации:
"=== PACKAGE INITIALIZATION SEQUENCE ===" - Вывести каждое сообщение об инициализации из среза
initLog - Вывести заголовок выполнения основной программы:
"=== MAIN PROGRAM EXECUTION ===" - Вывести:
"All packages initialized successfully" - Разобрать второй входной параметр, разделив его по запятым, чтобы получить отдельные операции
- Для каждой операции в основной программе:
- Вывести:
"Executing: [operation]" - Добавить сообщение в лог:
"[MAIN] Operation: [operation]" - Вывести сводку выполнения:
"=== EXECUTION SUMMARY ===""Packages initialized: [number_of_packages]""Main operations executed: [number_of_operations]""Total log entries: [total_number_of_log_entries]"- Вывести полный лог:
"=== COMPLETE EXECUTION LOG ==="- Вывести каждую запись из полного лога (как сообщения инициализации, так и основные операции)
- Вывести финальное сообщение:
"Program execution completed - all init functions ran before main"
Используйте пакет strings для разделения входных строк и пакет fmt для форматированного вывода. Эта задача демонстрирует, как функции init выполняются автоматически во время импорта пакета и всегда запускаются перед функцией main, что делает их идеальными для задач настройки и инициализации пакетов.
Шпаргалка
Функция init — это специальная функция в Go, которая запускается автоматически при импорте пакета:
package mypackage
import "fmt"
func init() {
fmt.Println("Package mypackage is being initialized!")
}Основные характеристики функций init:
- Не принимает параметров и не возвращает значений
- Запускается автоматически во время инициализации пакета
- Выполняется до начала работы функции
main - Идеально подходит для настройки начального состояния и выполнения разовых задач по настройке
- Срабатывает даже при импорте с использованием пустого идентификатора
Попробуйте сами
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// Глобальный срез для отслеживания сообщений инициализации
var initLog []string
func main() {
reader := bufio.NewReader(os.Stdin)
// Чтение ввода (bufio корректно обрабатывает строки с пробелами)
packageDefs, _ := reader.ReadString('\n')
packageDefs = strings.TrimRight(packageDefs, "\r\n")
mainOps, _ := reader.ReadString('\n')
mainOps = strings.TrimRight(mainOps, "\r\n")
// TODO: Напишите свой код ниже
// 1. Разберите packageDefs, разделив по ",", чтобы получить записи отдельных пакетов
// 2. Для каждой записи разделите по ":" (макс. 2 части), чтобы получить packageName и message
// 3. Создайте функцию logInit(packageName, message string), которая добавляет
// "[INIT] [packageName]: message" в глобальный срез initLog
// 4. Выведите заголовок последовательности инициализации и все записи лога инициализации
// 5. Выведите заголовок основного выполнения и обработайте каждую операцию из mainOps
// - Выведите "Executing: <op>" для каждой операции
// - Добавьте "[MAIN] Operation: <op>" в initLog
// 6. Выведите сводку выполнения (количество пакетов, количество операций, общее количество записей в логе)
// 7. Выведите полный лог и финальное сообщение о завершении
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутое управление потоком выполнения
Switch с использованием `fallthrough`Выход из вложенных цикловПродолжение конкретного циклаОператор `goto`Итоги: Продвинутое управление циклами4Проект: Простой список задач
Настройка проектаДобавление задачи2Структуры и методы
Определение методов для структурПолучатели по значениюПолучатели по указателюВыбор типа получателяМетоды против функцийИтоги: поведение структур5Карты: подробный разбор
Карты структурУказатели как значения картПроверка карт на nilСравнение картИтоги: счетчик частоты слов3Интерфейсы (Основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование интерфейсных типовПустой интерфейсУтверждение типаПереключатель типовИтоги: Фигуры и поведение6Идиоматичный Go: Множества
Идиома множества в GoСоздание множестваДобавление в множествоПроверка наличия элементаУдаление из множестваИтерация по множествуИтоги — Уникальные имена пользователей9Пакеты и область видимости
Что такое пакет?Экспортируемые и неэкспортируемые элементыСоздание простого пакетаПсевдонимы пакетовПустой идентификатор `_`Функция `init`Итоги: создание утилиты