Руководство: Начало работы с многомодульными рабочими пространствами

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

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

Примечание: Другие руководства смотрите в разделе Руководства.

Предварительные требования

  • Установленный Go версии 1.18 или новее.
  • Инструмент для редактирования кода. Подойдет любой текстовый редактор, который у вас есть.
  • Командный терминал. Go хорошо работает с любым терминалом на Linux и Mac, а также в PowerShell или cmd в Windows.

Это руководство требует go1.18 или новее. Убедитесь, что вы установили Go версии 1.18 или новее, используя ссылки на go.dev/dl.

Создание модуля для вашего кода

Для начала создайте модуль для кода, который вы будете писать.

  1. Откройте командную строку и перейдите в ваш домашний каталог.

    На Linux или Mac:

    <code>$ cd
    </code>

    На Windows:

    <code>C:\> cd %HOMEPATH%
    </code>

    В остальной части руководства будет показан символ $ в качестве приглашения. Команды, которые вы используете, будут работать и на Windows.

  2. Из командной строки создайте каталог для вашего кода с именем workspace.

    <code>$ mkdir workspace
    $ cd workspace
    </code>
  3. Инициализируйте модуль

    Наш пример создаст новый модуль hello, который будет зависеть от модуля golang.org/x/example.

    Создайте модуль hello:

    <code>$ mkdir hello
    $ cd hello
    $ go mod init example.com/hello
    go: creating new go.mod: module example.com/hello
    </code>

    Добавьте зависимость от пакета golang.org/x/example/hello/reverse, используя go get.

    <code>$ go get golang.org/x/example/hello/reverse
    </code>

    Создайте hello.go в каталоге hello со следующим содержимым:

    <code>package main
    import (
      "fmt"
      "golang.org/x/example/hello/reverse"
    )
    func main() {
      fmt.Println(reverse.String("Hello"))
    }
    </code>

    Теперь запустите программу hello:

    <code>$ go run .
    olleH
    </code>

Создание рабочего пространства

На этом шаге мы создадим файл go.work, чтобы указать рабочее пространство с модулем.

Инициализация рабочего пространства

В каталоге workspace выполните:

<code>$ go work init ./hello
</code>

Команда go work init говорит go создать файл go.work для рабочего пространства, содержащего модули в каталоге ./hello.

Команда go создает файл go.work, который выглядит так:

<code>go 1.18
use ./hello
</code>

Файл go.work имеет синтаксис, похожий на go.mod.

Директива go сообщает Go, с какой версией Go следует интерпретировать файл. Это похоже на директиву go в файле go.mod.

Директива use сообщает Go, что модуль в каталоге hello должен быть основным модулем при выполнении сборки.

Таким образом, в любом подкаталоге workspace модуль будет активен.

Запуск программы в каталоге рабочего пространства

В каталоге workspace выполните:

<code>$ go run ./hello
olleH
</code>

Команда Go включает все модули в рабочем пространстве как основные модули. Это позволяет нам ссылаться на пакет в модуле даже за пределами модуля. Запуск команды go run за пределами модуля или рабочего пространства приведет к ошибке, потому что команда go не будет знать, какие модули использовать.

Далее мы добавим локальную копию модуля golang.org/x/example/hello в рабочее пространство. Этот модуль хранится в подкаталоге репозитория Git go.googlesource.com/example. Затем мы добавим новую функцию в пакет reverse, которую сможем использовать вместо String.

Загрузка и изменение модуля golang.org/x/example/hello

На этом шаге мы загрузим копию репозитория Git, содержащего модуль golang.org/x/example/hello, добавим его в рабочее пространство, а затем добавим в него новую функцию, которую будем использовать в программе hello.

  1. Клонируйте репозиторий

    Из каталога workspace выполните команду git для клонирования репозитория:

    <code>$ git clone https://go.googlesource.com/example
    Cloning into 'example'...
    remote: Total 165 (delta 27), reused 165 (delta 27)
    Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done.
    Resolving deltas: 100% (27/27), done.
    </code>
  2. Добавьте модуль в рабочее пространство

    Репозиторий Git только что был извлечен в ./example. Исходный код модуля golang.org/x/example/hello находится в ./example/hello. Добавьте его в рабочее пространство:

    <code>$ go work use ./example/hello
    </code>

    Команда go work use добавляет новый модуль в файл go.work. Теперь он будет выглядеть так:

    <code>go 1.18
    use (
      ./hello
      ./example/hello
    )
    </code>

    Рабочее пространство теперь включает как модуль example.com/hello, так и модуль golang.org/x/example/hello, который предоставляет пакет golang.org/x/example/hello/reverse.

    Это позволит нам использовать новый код, который мы напишем в нашей копии пакета reverse, вместо версии пакета в кэше модулей, которую мы загрузили с помощью команды go get.

  3. Добавьте новую функцию.

    Мы добавим новую функцию для переворота числа в пакет golang.org/x/example/hello/reverse.

    Создайте новый файл с именем int.go в каталоге workspace/example/hello/reverse со следующим содержимым:

    <code>package reverse
    import "strconv"
    // Int returns the decimal reversal of the integer i.
    func Int(i int) int {
      i, _ = strconv.Atoi(String(strconv.Itoa(i)))
      return i
    }
    </code>
  4. Измените программу hello для использования функции.

    Измените содержимое workspace/hello/hello.go, чтобы оно содержало следующее:

    <code>package main
    import (
      "fmt"
      "golang.org/x/example/hello/reverse"
    )
    func main() {
      fmt.Println(reverse.String("Hello"), reverse.Int(24601))
    }
    </code>

Запуск кода в рабочем пространстве

Из каталога workspace выполните

<code>$ go run ./hello
olleH 10642
</code>

Команда Go находит модуль example.com/hello, указанный в командной строке, в каталоге hello, указанном файлом go.work, и аналогично разрешает импорт golang.org/x/example/hello/reverse, используя файл go.work.

go.work можно использовать вместо добавления директив replace для работы с несколькими модулями.

Поскольку оба модуля находятся в одном рабочем пространстве, легко внести изменения в один модуль и использовать их в другом.

Будущий шаг

Теперь, чтобы правильно выпустить эти модули, нам нужно будет сделать релиз модуля golang.org/x/example/hello, например, версии v0.1.0. Обычно это делается путем добавления тега к коммиту в системе контроля версий модуля. См. документацию по процессу выпуска модулей для получения более подробной информации. После завершения релиза мы можем увеличить требование к модулю golang.org/x/example/hello в hello/go.mod:

<code>cd hello
go get golang.org/x/example/hello@v0.1.0
</code>

Таким образом, команда go сможет правильно разрешать модули за пределами рабочего пространства.

Узнайте больше о рабочих пространствах

Команда go имеет несколько подкоманд для работы с рабочими пространствами в дополнение к go work init, которую мы видели ранее в руководстве:

  • go work use [-r] [dir] добавляет директиву use в файл go.work для dir, если она существует, и удаляет директиву use, если каталог-аргумент не существует. Флаг -r проверяет подкаталоги dir рекурсивно.
  • go work edit редактирует файл go.work аналогично go mod edit
  • go work sync синхронизирует зависимости из списка сборки рабочего пространства в каждый из модулей рабочего пространства.

См. раздел Рабочие пространства в справочнике по модулям Go для получения более подробной информации о рабочих пространствах и файлах go.work.

GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang