Оригинальная ссылка:Подробно о модулях Go
Go 1.11 и Go 1.12 содержат предварительныеGo ModulesДа, и Go 1.13, запланированный на август 2019 года, будет использовать модули Go по умолчанию во время всей разработки.
Go Modules предназначен для улучшения опыта использования кода других разработчиков, то есть для добавления зависимостей (модулей, пакетов), а также для обеспечения правильности и безопасности кода. А модули Go могут использовать переменную среды GOPROXY для решения проблемы, связанной с тем, что go get нельзя использовать в материковом Китае.
Поэтому необходимо узнать о модулях Go.
модель
Модули Go имеют три режима в Go 1.11 и Go 1.12, определяемые переменной среды GO111MODULE:
- Режим по умолчанию (эта переменная среды не установлена или
GO111MODULE=auto
): Инструменты командной строки Go используют модули Go, когда выполняются оба следующих условия:- Текущий каталог не находится в GOPATH/src/;
- Файл go.mod существует в текущем каталоге или в верхнем каталоге.
- режим GOPATH (
GO111MODULE=off
): инструменты командной строки Go никогда не используют модули Go. Вместо этого он ищет зависимости в каталоге поставщика и GOPATH. - Перейти в режим модулей (
GO111MODULE=on
): Инструменты командной строки Go используют только модули Go и никогда не обращаются к GOPATH. GOPATH больше не является каталогом импорта, но он по-прежнему хранит загруженные зависимости (GOPATH/pkg/mod/) и установленные команды (GOPATH/bin/), удаляется только GOPATH/src/.
В Go 1.13 по умолчанию используется шаблон Go Modules, поэтому сказанное выше можно игнорировать, как только Go 1.13 будет выпущен и будет использоваться в производстве.
Основной файл: go.mod
Ниже приведен наиболее полный пример файла go.mod:
module my/thing
go 1.12
require other/thing v1.0.2 // 这是注释
require new/thing/v2 v2.3.4 // indirect
require(
new/thing v2.3.4
old/thing v0.0.0-20190603091049-60506f45cf65
)
exclude old/thing v1.2.3
replace bad/thing v1.4.5 => good/thing v1.4.5
Он всеобъемлющий и сложный. Но на самом деле файл go.mod не так сложен в реальных проектах, и когда файл существует, никаких дополнительных шагов не требуется: такие команды, как go build, go test и даже go list, автоматически добавят новые зависимости, необходимые для выполнения импорта.
А теперь давайте более подробно рассмотрим состав файла go.mod:
Файл go.mod ориентирован на строки, текущий модуль (основной модуль) обычно находится в первой строке, за ним следуют зависимости, упорядоченные по пути.
Каждая строка содержит директиву, состоящую из начального глагола, за которым следуют аргументы.
Все ведущие глаголы функционируют следующим образом:
-
module
: укажите путь к модулю. -
go
: Установите ожидаемую языковую версию. -
require
: требуется определенный модуль данной версии или выше. -
exclude
: Исключает использование определенных версий модулей, запрещенные версии модулей считаются недоступными и не могут быть возвращены запросом. -
replace
: заменить исходную версию модуля другой версией модуля.
ведущие глаголы также могут бытькусок, создав блок со скобками (строки 5-8), как импорт в Go:
import (
"errors"
"fmt"
"log"
)
Комментарии (строки 3-4) можно использовать в одну строку// 这是注释
Комментарии, но не несколько строк/* 这是注释 */
Примечания. иindirect
Комментарий (строка 4) отмечает, что модуль не импортируется текущим модулем напрямую, а только косвенно.
Файл go.mod существует только в корневом каталоге модуля, путь импорта в подкаталоге будет использоватьпуть импорта модуля + путь подкаталогаформа. Например: если вы создаете подкаталог с именем world, вам не нужно использовать его в подкаталогеgo mod init
команда, инструмент командной строки Go автоматически распознает ее как часть модуля hello, поэтому ее путь импорта — hello/world.
Инструменты командной строки Go автоматически обрабатывают версию модуля, указанную в go.mod. в исходном кодеimport
Если указанный модуль не существует в файле go.mod, инструмент командной строки Go автоматически выполнит поиск модуля и добавит последнюю версию (последнюю помеченную и непредварительную стабильную версию) в файл go. файл мод.
Если тега нет, используется псевдоверсия (строка 7), которая представляет собой синтаксис версии, предназначенный для пометки нетегированных коммитов (некоторые пакеты на golang.org/x/ не имеют тегов). как:v0.0.0-20190603091049-60506f45cf65
.
Первая часть — это семантический номер версии, который используется для обозначения версии; средняя часть — это время фиксации в формате UTC, которое используется для сравнения двух псевдоверсий для определения порядка; последняя часть — это префикс версии. хэш коммита, который используется для обозначения того, где находится версия коммита.
Файл управления версиями: go.sum
Пример выглядит следующим образом:
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Каждая строка состоит из пути импорта модуля, конкретной версии модуля и ожидаемого хэша.
Каждый раз, когда модуль отсутствует, если он не существует в кеше, его необходимо загрузить и вычислить его хэш для добавления в go.sum; если он существует в кеше, он должен сопоставиться с существующей записью в go.sum.
Таким образом, пользователи, которые создают программное обеспечение, могут использовать хэш, чтобы убедиться, что их сборка такая же, как ваша сборка (go mod verify
) и получить одну и ту же версию независимо от того, как они извлекают зависимости. В то же время это также гарантирует, что зависимости проекта не будут иметь неожиданных вредоносных модификаций и других проблем. Вот почему файл go.sum добавлен в систему управления версиями (Git).
Плюс опция Go ModulesВыбор минимальной версииСтратегия (по умолчанию используется самая старая разрешенная версия каждого модуля, задействованного в сборке, чтобы выпуск новой версии не влиял на сборку) позволяет воспроизводимые сборки (с получением тех же результатов при повторных сборках).
Семантическое управление версиями
чтоСемантическое управление версиями? Semantic Versioning — это набор соглашений, установленных основателем Gravatar и соучредителем GitHub Томом Престоном-Вернером. В соответствии с этим набором соглашений семантические номера версий и то, как они обновляются, содержат много полезной информации.
Семантический формат номера версии:X.Y.Z
(основной номер версии. дополнительный номер версии. номер редакции), способ использования следующий:
- Увеличивайте основной номер версии при внесении изменений, не совместимых с предыдущими версиями.
- Дополнительный номер версии увеличивается, когда API остается обратно совместимым с новыми дополнениями и модификациями.
- Увеличивайте номер версии, когда проблема исправлена, не затрагивая API.
Например, есть семантический номер версии:v0.1.2
, основной номер версии — 0, дополнительный номер версии — 1 и номер редакции — 2. в то время как предыдущийv
— это первая буква версии (версия), которая используется соглашением языка Go, а стандартная семантическая версия не имеет этого соглашения.
Таким образом, при использовании инструмента командной строки Go или файла go.mod вы можете использовать семантический номер версии длязапрос модуля, конкретные правила заключаются в следующем:
- По умолчанию(
@latest
): будет соответствовать последней доступной версии с тегами или последней версии без тегов исходного репозитория. - полностью указанная версия (
@v1.2.3
): будет соответствовать указанной версии. - префикс версии (
@v1
или@v1.2
): будет соответствовать последней доступной версии тега с этим префиксом. - сравнение версий (
@<v1.2.3
или@>=v1.5.6
): будет соответствовать доступной версии тега, ближайшей к цели сравнения.<
последняя версия меньше той версии,>
Это самая старая версия больше, чем эта версия. При использовании Unix-подобной системы заключайте строку в кавычки, чтобы знаки больше или меньше не интерпретировались как перенаправление. как:go get 'github.com/gin-gonic/gin@<v1.2.3'
. - Укажите фиксацию (
@c856192
): будет соответствовать версии на момент фиксации. - укажите ветку(
@master
): будет соответствовать версии ветки.
Как показано на рисунке выше, чтобы упростить пользователям модулей Go переход со старой версии на новую, язык Go официально предлагает два важных правила:
- Правило совместимости импорта: если старый пакет и новый пакет имеют один и тот же путь импорта, новый пакет должен быть обратно совместим со старым пакетом.
- Правило управления версиями семантического импорта: каждая отдельная основная версия (т. е. несовместимый пакет
v1
илиv2
) с использованием разных путей импорта, заканчивающихся основной версией, и максимум одной из каждой основной версии. например: аrsc.io/quote
,Одинrsc.io/quote/v2
,Одинrsc.io/quote/v3
.
А интеграция с ветками Git выглядит следующим образом:
каталог поставщиков
Ранее каталог поставщиков использовался для двух целей:
- Точную версию зависимости можно использовать для сборки.
- Эти зависимости гарантированно будут доступны, даже если исходная копия исчезнет.
И модули теперь имеют лучший механизм для обоих:
- Указав точную версию зависимости в файле go.mod.
- Доступность определяется кэширующим прокси (
$GOPROXY
)выполнить.
И каталогу vendor тоже сложно управлять этими зависимостями, и со временем он попадет в ту же дилемму, что и черная дыра node_modules.
Таким образом, по умолчанию использование Go Modules полностью игнорирует зависимости от поставщиков, но для плавного перехода вы можете использоватьgo mod vendor
Команда может создать каталог поставщиков.
и используйте его в инструментах командной строки Go-mod=vendor
параметры, такие как:go test -mod=vendor ./...
; или установите для переменной среды GOFLAGS значение-mod=vendor
, который предполагает, что каталог поставщика содержит правильные копии зависимостей, и строит игнорируя описания зависимостей в файле go.mod.
Переменная среды GOPROXY
Установка переменной среды GOPROXY может решить проблему, из-за которой go get нельзя использовать в материковом Китае:
Пучокexport GOPROXY=https://goproxy.io
Просто напишите в конфигурационный файл Shell.
Общие команды
-
go mod init
: Создайте новый модуль, инициализируйте файл go.mod и параметром является путь импорта модуля.Эта форма рекомендуется. как:go mod init github.com/linehk/example
. -
go get
: изменить версию зависимости (или добавить новую). -
go build
,go test
И т. д. Команды: инструменты командной строки Go добавляют новые зависимости по мере необходимости. как:go test ./...
, чтобы протестировать текущий модуль. -
go list -m all
: Распечатать зависимости текущего модуля. -
go mod tidy
: Удалите бесполезные зависимости. -
go list -m -versions github.com/gin-gonic/gin
: Список всех версий этого модуля. -
go mod verify
: проверьте хэш.
Интеграция с GoLand
Для использования модулей Go в GoLand 2019.1.3 требуется две настройки:
- Настройки -> Go -> Go Modules (vgo), установите флажок Включить интеграцию Go Modules (vgo), чтобы включить Go Modules, и введите в поле ввода Proxy.
https://goproxy.io
. как показано на рисунке: - Настройки -> Перейти -> GOPATH, установите флажок Индексировать весь GOPATH, чтобы проиндексировать весь GOPATH, иначе пакет не может быть импортирован. как показано на рисунке:
После выполнения вышеуказанных настроек вы можете нажать Синхронизировать пакеты..., чтобы загрузить пакет при импорте пакета, которого нет в кеше: