Menu
Coddy logo textTech

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

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

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

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

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

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

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

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. Создать глобальный срез (slice) с именем 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, что делает их идеальными для задач настройки и инициализации пакетов.

Шпаргалка

Функция 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. Выведите полный лог и финальное сообщение о завершении

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

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

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