Как Go управляет пакетами и модулями? Что такое go.mod?
Модуль — единица версионирования, описанная файлом go.mod с путём, версией Go и зависимостями (semver). Пакет — единица компиляции внутри модуля. go mod tidy синхронизирует зависимости.
Пакеты и модули в Go
Пакет (package) — единица компиляции и пространства имён. Каждый .go-файл начинается с директивы package <name>. Пакеты из одной директории образуют один пакет.
Модуль (module) — единица версионирования и дистрибуции. Корень модуля определяется файлом go.mod. Один модуль содержит множество пакетов.
Файл go.mod
go.mod хранит три ключевых секции:
module— путь модуля (import path), напримерgithub.com/company/myapp.go— минимальная версия Go (go 1.22).require— прямые и транзитивные зависимости с точными версиями (semver).
module github.com/company/myapp
go 1.22
require (
github.com/gin-gonic/gin v1.9.1
golang.org/x/sync v0.6.0
)
Файл go.sum
go.sum содержит криптографические хэши (SHA-256) всех загруженных модулей. Это защита от подмены — если хэш не совпадает, сборка падает. Файл должен быть зафиксирован в репозитории.
Основные команды
go mod init github.com/company/myapp # создать новый модуль
go get github.com/gin-gonic/gin@v1.9.1 # добавить/обновить зависимость
go mod tidy # удалить неиспользуемые, добавить недостающие
go mod download # скачать все зависимости в кэш
go mod vendor # скопировать deps в папку vendor/
go list -m all # показать все зависимости
Workspace (go.work, Go 1.18+)
Для локальной разработки нескольких модулей одновременно используют go work:
go work init ./app ./lib
# создаёт go.work:
# use (
# ./app
# ./lib
# )
Go подменяет сетевые зависимости локальными путями без изменения go.mod.
Версионирование major
Для major-версий v2+ путь модуля должен заканчиваться на /v2: github.com/company/myapp/v2. Иначе go get не найдёт пакет.
Подводные камни
- Путь модуля в
go.modдолжен точно совпадать с тем, что написано вimport— любое расхождение даёт ошибку компиляции. - Не фиксировать
go.sumв репозитории — это нарушает воспроизводимость сборки и CI. - Отсутствие
go mod tidyперед коммитом оставляет «мусорные» записи вrequireи нарушает проверки в CI (go mod tidy -check). - Смешивание
GOPATH-режима и модульного режима (переменнаяGO111MODULE=off) ломаетgo getна современных версиях. - При использовании
replace-директив вgo.modлокальный путь не распространяется на потребителей библиотеки —replaceработает только в корневом модуле. - Циклические зависимости между пакетами одного модуля запрещены и дают ошибку компилятора; архитектурное решение — выделить общий пакет.
- Версия
goвgo.modвлияет на семантику языка: с Go 1.21 она стала минимальной требуемой версией, а не просто подсказкой.
Common mistakes
- Давать ответ про packages, modules и go.mod только на уровне определения, не показывая поведение в реальном приложении.
- Игнорировать границы ответственности вокруг темы «packages, modules и go.mod»: кто отменяет работу, кто владеет ресурсом и где формируется ответ клиенту.
- Не связывать packages, modules и go.mod с observability, тестированием или безопасностью, когда это влияет на продакшен-поведение.
What the interviewer is testing
- Точно объясняет, что именно делает packages, modules и go.mod и где это используется в Go-коде.
- Связывает packages, modules и go.mod с корректным lifecycle запроса, отменой, конкурентностью или конфигурацией сервера там, где это уместно.
- Не изобретает API и опирается на реальные контракты официальной документации.