Уроки модуля (4/5)
Модули Go
Модуль Go — это модуль с поддержкой версий, состоящий из одного или нескольких пакетов. Это основа современной системы зависимостей (Go 1.11+): больше никаких GOPATH, никаких обязательных vendor, явные и воспроизводимые зависимости.
go.mod: манифест модуля
module example.com/myapp
go 1.22
require (
github.com/google/uuid v1.6.0
golang.org/x/time v0.5.0
)
Три основные директивы:
module <path>— путь импорта модуля. Все внутренние пакеты импортируются какexample.com/myapp/sub/pkg. Это не обязательно должен быть настоящий URL-адрес, но для публикации черезgo getон должен быть разрешен.go <version>— минимальная требуемая версия Go (также используется для управления тем, какие языковые функции разрешены, например, range-over-func в 1.23).require— прямые зависимости с их точной версией.
Другие директивы: replace (заменяет dep ответвлением или локальным путем), exclude, retract.
go.sum: файл криптографической блокировки.
Наряду с go.mod, go.sum содержит криптографический хеш КАЖДОЙ загруженной версии (включая транзитивные зависимости). Это гарантирует воспроизводимость: если кто-то подделает опубликованную версию, сборка завершится неудачей.
Всегда фиксируйте его. Он обновляется автоматически командами go.
Основные команды
go mod init example.com/myapp # create go.mod
go get github.com/google/uuid # add the dep at its latest version
go get github.com/google/uuid@v1.5.0 # specific version
go get -u ./... # upgrade every dep
go mod tidy # remove unused deps, add missing ones
go mod download # download everything into the cache
go mod why github.com/x/y # explain why a dep is included
go mod graph # full dependency graphgo mod tidy — это тот, который вы запускаете после каждого изменения импорта: он гарантирует, что go.mod точно отражает фактически используемые пакеты.
Семантическое управление версиями импорта (SIV)
Версии соответствуют SemVer: v1.2.3 = MAJOR.MINOR.PATCH. Самое интересное — major v2+:
- Основные
v0иv1→ обычный путь:github.com/foo/bar. - Основная версия
v2или более поздняя → путь включает основную версию:github.com/foo/bar/v2.
import "github.com/foo/bar/v2"Это позволяет одновременно импортировать v1 и v2 одной и той же библиотеки (полезно при прогрессивной миграции).
Импорт путей и внутренних пакетов
Если ваш модуль example.com/myapp, подпапка utils/ импортируется как:
import "example.com/myapp/utils"Путь зависит только от имени, объявленного в go.mod, а не от местоположения на диске: тот же код в другой папке продолжает работать.
Режим рабочей области (Go 1.18+)
Чтобы работать с несколькими модулями, которые ссылаются друг на друга одновременно (например, с библиотекой и приложением, которое ее использует):
go work init ./lib ./appПри этом создается go.work: go build будет использовать локальную версию ./lib вместо загрузки опубликованной. Не делайте коммит go.work (это среда разработки).
Упражнения
Модуль находится по адресу example.com/myapp и содержит подпапку utils. Импортируйте подпакет в основной, используя полный путь.
Показать подсказку
Путь импорта — это имя модуля (из go.mod) плюс относительный путь к папке.
Решение доступно после 3 попыток
Превратите отдельные импортированные файлы в группу импорта с помощью синтаксиса импорта (...), импортируя как fmt, так и os.
Решение доступно после 3 попыток
Какая команда удаляет зависимости, которые больше не импортируются из go.mod, и добавляет недостающие?
$ go mod ???