Menu
CoddyTech

Функция `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, ты сразу увидишь её эффекты, даже если не используешь ни одну из экспортируемых функций пакета. Именно поэтому изученный ранее шаблон импорта с пустым идентификатором так полезен — он позволяет запустить инициализацию пакета, не используя его код напрямую.

challenge icon

Задание

Легко

Создай систему инициализации пакетов, которая демонстрирует, как функции 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")

Твоя задача:

  1. Разобрать первый вход, разделив его по запятым, чтобы получить отдельные определения пакетов
  2. Для каждого определения пакета разделить его по двоеточиям, чтобы получить имя пакета и сообщение об инициализации
  3. Создать глобальный срез с именем initLog для отслеживания сообщений об инициализации
  4. Создать функцию с именем logInit, которая принимает имя пакета и сообщение, а затем добавляет отформатированное сообщение "[INIT] [package_name]: [message]" в срез initLog
  5. Смоделировать инициализацию пакетов, вызвав logInit для каждого пакета в том порядке, в котором они указаны во входных данных
  6. Вывести заголовок последовательности инициализации: "=== PACKAGE INITIALIZATION SEQUENCE ==="
  7. Вывести каждое сообщение об инициализации из среза initLog
  8. Вывести заголовок основной программы: "=== MAIN PROGRAM EXECUTION ==="
  9. Вывести: "All packages initialized successfully"
  10. Разобрать второй вход, разделив его по запятым, чтобы получить отдельные операции
  11. Для каждой операции в основной программе:
    • Вывести: "Executing: [operation]"
    • Добавить сообщение в журнал: "[MAIN] Operation: [operation]"
  12. Вывести сводку выполнения:
    • "=== EXECUTION SUMMARY ==="
    • "Packages initialized: [number_of_packages]"
    • "Main operations executed: [number_of_operations]"
    • "Total log entries: [total_number_of_log_entries]"
  13. Вывести полный журнал:
    • "=== COMPLETE EXECUTION LOG ==="
    • Вывести каждую запись из полного журнала (сообщения об инициализации и операции основной программы)
  14. Вывести заключительное сообщение: "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. Выведите полный журнал и итоговое сообщение о завершении

}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Онлайн-компилятор Go