go.mod и go mod tidy
В первом уроке темы вы видели первую строку go.mod — адрес завода на воротах. Но в задачах курса вы ни разу не создавали go.mod сами. Почему? Каждая задача на этом сайте собирается внутри готового модуля, который проверяющая программа пишет за вас:
module sandbox
go 1.26На своём компьютере модуль придётся завести самому. Это делает команда go mod init с путём модуля: go mod init example.com/shop, запущенная в папке проекта, создаёт там go.mod с первой строкой module example.com/shop. Как поставить Go, рассказано в блоке «Подготовка компьютера» на странице курса. А в этом уроке разберём, что лежит в go.mod и как его поддерживать в порядке.
Вернёмся на завод. У ворот висит паспорт завода: адрес и список поставщиков, у которых завод берёт детали. Рядом журнал с номерами пломб на каждой полученной партии. А по цехам ходит кладовщик: что нужно, а не заказано, — заказывает, а от ненужного отказывается. В Go паспорт — это go.mod, журнал пломб — go.sum, а кладовщик — команда go mod tidy.
Что лежит в go.mod
Файл go.mod — короткий текст из трёх видов строк:
module— путь модуля, с которого начинаются пути импорта всех его пакетов;go— версия языка, на которую рассчитан код;require— чужой модуль, который нужен коду, и его версия.
Пока проект пользуется только стандартной библиотекой, строк require нет. Пакеты вроде fmt и strings приходят вместе с Go и в go.mod не записываются.
Чужой модуль в проекте
Допустим, программе нужны уникальные идентификаторы. Их умеет делать пакет uuid из модуля github.com/google/uuid. Вот программа, которая его импортирует:
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
id := uuid.New()
fmt.Println(len(id.String())) // 36
}Разберём её по строкам:
- Путь импорта начинается с адреса чужого модуля,
github.com/google/uuid. uuid.New()создаёт новый случайный идентификатор.id.String()превращает его в строку, а программа печатает её длину:36.
Модуль uuid нужно скачать и записать в go.mod. Это и делает go mod tidy — команда, которая приводит go.mod в соответствие с импортами кода:
$ go mod tidy
go: finding module for package github.com/google/uuid
go: found github.com/google/uuid in github.com/google/uuid v1.6.0Команда нашла импорт, скачала последнюю версию модуля и дописала в go.mod строку require:
module example.com/shop
go 1.26
require github.com/google/uuid v1.6.0Файл go.sum
Вместе с go.mod появился второй файл — go.sum. В нём контрольные суммы скачанного модуля:
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=Это номера пломб из журнала. Когда модуль скачают снова, на другом компьютере или через год, Go сверит содержимое с этими суммами. Если хоть один байт отличается, сборка остановится. Поэтому go.mod и go.sum всегда хранят и передают вместе с кодом проекта.
Когда модуль больше не нужен
Теперь уберём из main.go импорт uuid и снова запустим go mod tidy. Команда ничего не печатает, но go.mod возвращается к прежнему виду:
module example.com/shop
go 1.26Строка require исчезла, а строки модуля uuid пропали и из go.sum. Кладовщик отказался от поставщика, которым больше никто не пользуется.
Здесь картинка с кладовщиком перестаёт работать. Настоящий кладовщик обходит цеха сам, каждый день. go mod tidy ничего не делает, пока вы её не запустите, поэтому её запускают после каждого изменения импортов.
Частая ошибка
Импорт чужого модуля добавили, а go mod tidy запустить забыли:
import "github.com/google/uuid" // ✗no required module provides package github.com/google/uuid; to add it:
go get github.com/google/uuidСборка останавливается: в go.mod нет строки require для этого модуля, и Go не знает, какую версию взять. Go предлагает go get, но go mod tidy тоже подойдёт: она добавит все недостающие модули сразу.
Главное
- go.mod хранит путь модуля, версию Go и строки
requireс чужими модулями. go mod init <путь>создаёт go.mod в папке проекта.- go.sum хранит контрольные суммы скачанных модулей; оба файла хранят вместе с кодом проекта.
go mod tidyдописываетrequireдля каждого импортированного чужого модуля и удаляет ненужные.- Задачи курса собираются в готовом модуле
sandbox, поэтому go.mod в них не нужен.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.