По официальной документации, модуль — это коллекция пакетов с общими версионированием и релизным циклом. Модули могут загружаться либо напрямую из систем контроля версий, либо с модульных прокси-серверов. О том, как устанавливать модули из внешних источников, поговорим в следующем уроке.
Проще говоря, это группа пакетов, которые хранятся и обновляются вместе. Даже ваше приложение будет являться модулем.
Метаинформация о модуле содержится в файле go.mod
в корневой директории модуля. Полный список всех директив этого файла можно также найти в документации.
Метаинформация о модуле говорит о том, как он будет собираться, экспортироваться и какие будет использовать внешние зависимости.
Разберём несколько базовых директив на примере создания локальных модулей, то есть расположенных в нашей файловой системе. Пример базируется на Go 1.17, поэтому в других версиях некоторые моменты могут отличаться.
Создание модуля
Создадим новую директорию ypmodule
:
Инициализируем модуль внутри директории стандартной утилитой go mod
:
В директории создался файл go.mod
, содержащий:
module ypmodule
go 1.17
Строка module ypmodule
содержит путь импорта модуля — это префикс, относительно которого будут импортироваться все пакеты этого модуля. Например, чтобы импортировать пакет somepackage
из модуля ypmodule
, надо добавить в код строку:
import "ypmodule/somepackage"
Следует отметить, что в большинстве случаев файл go.mod
не редактируется вручную, а изменяется с помощью go mod
.
В примере путь импорта — это одно слово ypmodule
. Но путь может быть и полноценным URL. Например, github.com/someuser/somerepo
. Такие пути будут рассмотрены далее.
Строка go 1.17
указывает на версию Go, использованную при создании этого модуля.
Создадим в модуле пакет calc
для работы с числами и поместим в него файл math.go
с функцией сложения целых чисел.
В примере для модуля calc
создана отдельная директория. Но если не предполагается добавлять в модуль больше одного пакета, можно писать код прямо в директории с файлом go.mod
.
Чтобы протестировать функциональность модуля, создадим рядом с ypmodule
ещё один модуль — main
. Файловая структура будет выглядеть так:
.
├── main
└── ypmodule
├── calc
│ └── math.go
└── go.mod
Для создания нового модуля выполним в main
команду:
Создадим в новом модуле файл main.go
, содержащий:
Попробуем запустить функцию main
. И получим ошибку:
main.go:6:2: package ypmodule/calc is not in GOROOT (/usr/local/go/src/ypmodule/calc)
Дело в том, что в файле main/go.mod
не описано, где искать модуль ypmodule
. Сначала Go пошёл в GOROOT
и не обнаружил его. Затем Go увидел, что ypmodule
не похож на URL, поэтому искать этот пакет в сети нет смысла.
Поскольку сейчас работаем с локальным модулем (то есть его код лежит только на нашей файловой системе), для определения его положения на локальном диске нужно воспользоваться директивой replace. После её добавления файл main/go.mod
будет выглядеть так:
module main
go 1.17
// директивой replace указываем положение корня
// модуля ypmodule относительно main/go.mod
replace ypmodule => ../ypmodule
Так как ypmodule
содержит внутри себя другие пакеты и зависимости, их тоже нужно указать. Можно не знать о зависимостях и структуре этого модуля, но инструментарий в Go придёт на помощь.
Выполним команду go get ypmodule
:
go get ypmodule
go get: added ypmodule v0.0.0-00010101000000-000000000000
В go.mod
появилась строка:
require ypmodule v0.0.0-00010101000000-000000000000 // indirect
Она указывает, какую конкретно версию модуля ypmodule
будет использовать main
при сборке. Комментарий // indirect
подсказывает, что сам пакет ypmodule
в коде не импортируется, только calc
.
Запустим main
ещё раз. Ура, всё заработало! Первые локальные модули успешно нашли друг друга.
Когда нужно применять модули?
На практике — всегда. Модули дают разработчику очень много возможностей по управлению зависимостями программы. Не стоит опасаться лишней сложности выполнения, так как почти всю работу по настройке модуля за вас может сделать среда разработки и инструментарий Go.
📂 Go | Последнее изменение: 23.08.2024 08:53