До свидания, ГОПАТ! Введение в управление пакетами в новой версии Golang

Go

В Go 1.11 и 1.12 реализована первоначальная поддержка управления пакетами, а новая система управления зависимостями Go делает информацию о версии зависимостей явной и простой в управлении.Using Go Modules - The Go Blog

Golang

Чем отличается новая модель управления пакетами?

Как пропагандисту языка Go мне часто задают различные вопросы об основных особенностях языка Go. Среди них вопросы об управлении пакетами дали бы мнеочень смущен, потому что управление пакетами в Go до версии 1.11 на самом деле только ""по сравнению с Python, Node и Java.доступен только"Вот и все.

так как:

  1. Зависимости Go нужно скачивать вручную без использования дополнительных инструментов,
  2. Сторонние пакеты не имеют понятия версии, и если автор стороннего пакета сделает несовместимый апгрейд, то разработчикам будет очень некомфортно.
  3. При совместной разработке необходимо унифицировать локальные$GOPATH/srcПакет зависимостей под
  4. Ссылающаяся пакет относится к пакету, которое было передано, и если автор не изменил его, ему нужно самому модифицировать ссылку.
  5. Исходный код сторонних пакетов и их собственные пакеты находятся в src, что очень сбивает с толку. Для проектов со смешанными стеками технологий возникнут некоторые проблемы с хранением каталогов.

Новый режим управления пакетами решает вышеуказанные проблемы

  1. Автоматически загружать пакеты зависимостей
  2. Проекты больше не должны находиться в GOPATH/src
  3. В проекте будет сгенерирован файл go.mod со списком зависимостей пакетов.
  4. Так приходящий сторонний пакет будет точно указывать номер версии
  5. Для пакетов, которые были переданы, вы можете использовать оператор replace для замены без изменения кода.

Давайте начнем с небольшого примера, чтобы проиллюстрировать проблему!

Готов к работе

  1. Обновите версию golang до 1.12.Перейти скачать
  2. добавить переменную окруженияGO111MODULEзаonилиauto
GO111MODULE=auto

Готово, очень просто! !

Создать проект

Первый в$GOPATH/srcСоздайте каталог за пределами пути, где вам нравится, перейдите в каталог и создайте новый файл hello.go со следующим содержимым.

package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello, world!")
}

Инициализировать модуль

В текущем каталоге командная строка запускает go mod init + имя модуля для инициализации модуля.

go mod init hello

После запуска файл будет сгенерирован в текущем каталоге проекта.go.modфайл, это ключевой файл, и последующее управление пакетами осуществляется через этот файл.

Официальное примечание. В дополнение к файлу go.mod команда go поддерживает файл с именем go.sum, который содержит ожидаемый криптографический хэш содержимого конкретной версии модуля.
Команда go использует файл go.sum, чтобы убедиться, что будущие загрузки этих модулей получают те же биты, что и при первой загрузке, чтобы гарантировать, что модули, от которых зависит проект, не будут случайно изменены, будь то злонамеренные, случайные или иные. И go.mod, и go.sum должны быть проверены в системе контроля версий.
go.sumНикакого ручного обслуживания не требуется, поэтому его можно выполнять без особого внимания.

Сгенерированный файл содержит имя модуля и номер текущей версии go.

module hello

go 1.12

Уведомление: Init не требуется в подкаталогах, все зависимости в подкаталогах будут организованы в файле go.mod в корневом каталоге

Давай, сделай что-нибудь маленькое и посмотри, как работает go.mod

Затем сделайте ваш проект зависимым от сторонних пакетов. Возьмем, к примеру, beego, с которым знакомо большинство людей! Измените файл Hello.go:

package main

import "github.com/astaxie/beego"

func main() {
    beego.Run()
}

Как и раньше, для запуска hello.go нужно выполнитьgo getКоманда Загрузите пакет beego в $GOPATH/src

Однако с новым управлением пакетами в этом больше нет необходимости.

непосредственныйgo run hello.go

Подождите... go автоматически найдет пакеты в коде, загрузит зависимости и запишет конкретные зависимости и версии в файлы go.mod и go.sum. Глядя на go.mod, становится так:

module hello

go 1.12

require github.com/astaxie/beego v1.11.1

requireКлючевая подпрограмма — это ссылка, за которой следует пакет, и, наконец, v1.11.1 — это номер версии ссылки.

На этом небольшой пример создания проекта с использованием метода управления пакетами Go завершен.

Итак, далее несколько небольших вопросов

Вопрос 1: Где загружаются зависимые пакеты? Все еще в GOPATH?

нет.Используя метод управления пакетами Go, зависимые сторонние пакеты загружаются в$GOPATH/pkg/modпод дорожкой.

Если вы успешно запустите этот пример, вы можете$GOPATH/pkg/modНайдите такой пакетgithub.com/astaxie/beego@v1.11.1

Вопрос 2: Как контролируется версия зависимого пакета?

В предыдущем вопросе вы можете видеть, что окончательная загрузка находится в$GOPATH/pkg/modпакет подgithub.com/astaxie/beego@v1.11.1В конце будет номер версии 1.11.1, то есть$GOPATH/pkg/modТам могут быть сохранены разные версии того же пакета.

Версии указаны в go.mod.

Если он не указан в go.mod, то команда go автоматически скачает последнюю версию зависимостей в коде, в этом случае автоматически загружается последняя версия.

Если пакет и версия указаны в операторе require в go.mod, команда go загрузит пакет в соответствии с указанным путем и версией, Доступно при указании версииlatest, поэтому он автоматически загрузит последнюю версию указанного пакета;

Каков номер версии пакета зависимостей?Это номер версии, отмеченный издателем пакета, в формате vn.n.n (n представляет число).Историческую версию beego в этом примере можно увидеть в выпуске репозитория кода.Releases · astaxie/beego · GitHub

По умолчанию v0.0.0, если автор пакета не отметил версию.

Вопрос 3: Можно ли разместить проект под $ Gopath / SRC?

Может.Но go будет использовать разные методы обработки в зависимости от значения GO111MODULE. по умолчанию,GO111MODULE=autoавтоматический режим

  • autoВ автоматическом режиме элемент$GOPATH/srcбуду использовать$GOPATH/srcПакет зависимостей вне $GOPATH/src, используйте пакет, требуемый в go.mod
  • onНа моде, после 1.12, вне зависимости от$GOPATH/srcБудь то внутри или снаружи, будут использоваться пакеты, необходимые в go.mod.
  • offВыключенный режим — это старое правило.

Вопрос 3. Что делать, если адрес в пакете зависимостей недействителен? Например, что мне делать, если пакеты из golang.org/x/… не загружаются?

Во время быстрой разработки go некоторые адреса пакетов зависимостей изменились. предыдущая практика

  1. Измените исходный код и замените адрес импорта новым путем.
  2. После клонирования git или получения нового пакета скопируйте старый путь в $GOPATH/src Независимо от того, какой метод используется, его нелегко поддерживать, особенно когда несколько человек разрабатывают совместно.

Использовать go.mod просто, в go.mod замените файл замены на пакет, например,

replace golang.org/x/text => github.com/golang/text latest

Таким образом, go заменит golang.org/x/text на github.com/golang/text, принцип заключается в том, чтобы загрузить последнюю версию github.com/golang/text на$GOPATH/pkg/mod/golang.org/x/textВниз.

Вопрос 4: Каково использование имени модуля go.mod, сгенерированного init?

В этом примере первая строка в файле go.mod, сгенерированном с помощью go mod init hello, будет объявлятьmodule hello

потому что нашего проекта больше нет$GOPATH/srcТак что насчет того, чтобы цитировать себя? Просто используйте имя модуля + путь.

Например, создайте новый каталог utils в проекте и создайте файл tools.go:

package utils

import “fmt”

func PrintText(text string) {
	fmt.Println(text)
}

Файл hello.go в корневом каталоге может импортировать «hello/utils» для ссылки на utils.

package main

import (
"hello/utils"

"github.com/astaxie/beego"
)

func main() {

	utils.PrintText("Hi")

	beego.Run()
}


Вопрос 5: Как управлять старыми проектами с новыми пакетами

  1. Если вы используете автоматический режим, переместите элемент в$GOPATH/srcза пределами
  2. войдите в каталог, запуститеgo mod init + 模块名称
  3. go buildилиgo runоднажды

Вот и все введение в управление пакетами в Go 1.12.

Согласно официальному заявлению, начиная с Go 1.13 режим управления модулями будет режимом по умолчанию для разработки языка Go.

Итак, набирай!

Если у вас есть какие-либо вопросы или вам нужно обсудить, вы можете оставить мне сообщение,учиться вместе, прогрессировать вместе

Сяо код общедоступный номер:

晓代码公众号