По официальной документации, модуль — это коллекция пакетов с общими версионированием и релизным циклом. Модули могут загружаться либо напрямую из систем контроля версий, либо с модульных прокси-серверов. О том, как устанавливать модули из внешних источников, поговорим в следующем уроке.
Проще говоря, это группа пакетов, которые хранятся и обновляются вместе. Даже ваше приложение будет являться модулем.
Метаинформация о модуле содержится в файле go.mod в корневой директории модуля. Полный список всех директив этого файла можно также найти в документации.
Метаинформация о модуле говорит о том, как он будет собираться, экспортироваться и какие будет использовать внешние зависимости.
Разберём несколько базовых директив на примере создания локальных модулей, то есть расположенных в нашей файловой системе. Пример базируется на Go 1.17, поэтому в других версиях некоторые моменты могут отличаться.
Создание модуля
Создадим новую директорию ypmodule:
mkdir ypmodule
cd ypmodule Инициализируем модуль внутри директории стандартной утилитой go mod:
go mod init ypmodule В директории создался файл 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 с функцией сложения целых чисел.
package calc
 
func AddInts(a, b int) int {
    return a + b
} В примере для модуля calc создана отдельная директория. Но если не предполагается добавлять в модуль больше одного пакета, можно писать код прямо в директории с файлом go.mod.
Чтобы протестировать функциональность модуля, создадим рядом с ypmodule ещё один модуль — main. Файловая структура будет выглядеть так:
.
├── main
└── ypmodule
    ├── calc
    │   └── math.go
    └── go.mod 
Для создания нового модуля выполним в main команду:
go mod init main Создадим в новом модуле файл main.go, содержащий:
package main
 
import (
    "fmt"
 
    "ypmodule/calc"
)
 
func main() {
    fmt.Println(calc.AddInts(1, 2))
} Попробуем запустить функцию 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