Собственные пакеты: структура папок, exported и unexported имена
Содержание курса
До этого момента весь код жил в одном файле или в одной папке с пакетом main. Как только проект растёт — появляются вспомогательные функции, которые хочется переиспользовать — нужна другая структура. Go решает это очень конкретно: одна папка = один пакет.
Структура папок модуля и объявление пакетов main и mathutil
Создадим папку проекта и инициализируем модуль:
mkdir myapp && cd myapp go mod init example.com/myapp
Команда go mod init не создаёт никаких вложенных папок с именем модуля — она просто записывает module path в файл go.mod текущего каталога. Физическая структура на диске выглядит так:
myapp/
├── go.mod
├── main.go
└── mathutil/
└── mathutil.go
А содержимое go.mod — вот так:
module example.com/myapp go 1.21
example.com/myapp — это module path: строка-идентификатор модуля, которую Go использует при импорте пакетов. Она не обязана совпадать с именем папки на диске; папка называется myapp, а module path — example.com/myapp.
Файл main.go начинается с package main — это точка входа. Файл mathutil/mathutil.go начинается с package mathutil. Это всё, что требуется от каждого файла: объявить, к какому пакету он принадлежит.
Главное правило: все .go-файлы в одной папке должны объявлять одно и то же имя пакета. Попытка смешать package mathutil и package util в одной папке приведёт к ошибке компиляции. Компилятор считает папку единицей: он компилирует всё содержимое сразу и требует единого package-объявления.
Имя папки и имя пакета принято делать одинаковыми — mathutil/ содержит package mathutil. Технически компилятор не требует этого совпадения, но весь инструментарий Go (включая go doc и большинство IDE) рассчитывает именно на такое соответствие.
Если хочется добавить ещё одну группу функций — создаём ещё одну подпапку со своим .go-файлом и своим package-объявлением. Глубина вложенности не ограничена, но каждая папка всё равно остаётся одним пакетом.
