По официальной документации, модуль — это коллекция пакетов с общими версионированием и релизным циклом. Модули могут загружаться либо напрямую из систем контроля версий, либо с модульных прокси-серверов. О том, как устанавливать модули из внешних источников, поговорим в следующем уроке.

Проще говоря, это группа пакетов, которые хранятся и обновляются вместе. Даже ваше приложение будет являться модулем.

Метаинформация о модуле содержится в файле 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