Перейти к содержимому
Теория · От файла к проекту · урок 3 из 10

go.mod и go mod tidy

В первом уроке темы вы видели первую строку go.mod — адрес завода на воротах. Но в задачах курса вы ни разу не создавали go.mod сами. Почему? Каждая задача на этом сайте собирается внутри готового модуля, который проверяющая программа пишет за вас:

TEXT
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. Вот программа, которая его импортирует:

GO
package main

import (
    "fmt"

    "github.com/google/uuid"
)

func main() {
    id := uuid.New()
    fmt.Println(len(id.String())) // 36
}

Разберём её по строкам:

  1. Путь импорта начинается с адреса чужого модуля, github.com/google/uuid.
  2. uuid.New() создаёт новый случайный идентификатор.
  3. id.String() превращает его в строку, а программа печатает её длину: 36.

Модуль uuid нужно скачать и записать в go.mod. Это и делает go mod tidy — команда, которая приводит go.mod в соответствие с импортами кода:

TEXT
$ 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:

TEXT
module example.com/shop

go 1.26

require github.com/google/uuid v1.6.0

Файл go.sum

Вместе с go.mod появился второй файл — go.sum. В нём контрольные суммы скачанного модуля:

TEXT
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 возвращается к прежнему виду:

TEXT
module example.com/shop

go 1.26

Строка require исчезла, а строки модуля uuid пропали и из go.sum. Кладовщик отказался от поставщика, которым больше никто не пользуется.

Здесь картинка с кладовщиком перестаёт работать. Настоящий кладовщик обходит цеха сам, каждый день. go mod tidy ничего не делает, пока вы её не запустите, поэтому её запускают после каждого изменения импортов.

Частая ошибка

Импорт чужого модуля добавили, а go mod tidy запустить забыли:

GO
import "github.com/google/uuid" // ✗
TEXT
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 и подпишись на канал — откроются все уроки.

Войти другим способом