Функция `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")
Твоя задача:
- Разобрать первый вход, разделив его по запятым, чтобы получить отдельные определения пакетов
- Для каждого определения пакета разделить его по двоеточиям, чтобы получить имя пакета и сообщение об инициализации
- Создать глобальный срез с именем
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, что делает их идеальным инструментом для настройки и инициализации пакетов.
Попробуйте сами
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Сравнение картПовторение — счётчик частоты слов8Проект: простой складской учёт
Обзор проектаПроверка запасов3Интерфейсы (основы)
Что такое интерфейс?Определение интерфейсаРеализация интерфейсаИспользование типов интерфейсовПустой интерфейсУтверждения типовПереключатель типовПовторение — формы и поведение6Идиоматический Go: множества
Идиома множества в GoСоздание множестваДобавление элементов в множествоПроверка наличия элементаУдаление элемента из множестваПеребор элементов множестваПовторение — уникальные имена пользователей9Пакеты и область видимости
Что такое пакет?Экспортируемые и неэкспортируемыеСоздание простого пакетаПсевдонимы пакетовПустой идентификатор `_`Функция `init`Повторение — создание утилитыПотренируйтесь самостоятельно: Онлайн-компилятор Go