Tutorial

Импорт пакетов в Go

GoDevelopment

Введение

Иногда для вашего кода могут потребоваться дополнительные функции вне текущей программы. В подобных случаях вы можете использовать пакеты, чтобы сделать программу более функциональной. Пакет представляет собой все файлы в одном каталоге на диске. Пакеты могут определять функции, типы и интерфейсы, на которые вы можете ссылаться в других файлах или пакетах Go.

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

Пакеты стандартной библиотеки

Стандартная библиотека, входящая в комплект Go, представляет собой набор пакетов. Эти пакеты содержат множество фундаментальных компонентов для современного программного обеспечения. Например, пакет fmt содержит базовые функции для форматирования и вывода строк. Пакет net/http содержит функции, позволяющие разработчику создавать веб-службы, отправлять и получать данные по протоколу http и т. д.

Чтобы использовать функции пакета, необходимо получить доступ к нему с помощью выражения import. Выражение import состоит из ключевого слова import и имени пакета.

Например, в файле программы Go с именем random.go вы можете импортировать пакет math/rand для генерирования случайных чисел с помощью следующей команды:

random.go
import "math/rand"

При импорте пакета мы делаем его доступной в текущей программе в качестве отдельного пространства имен. Это означает, что мы будем ссылаться на функцию в точечной нотации, например package.function.

На практике функция из пакета math/rand может выглядеть, как показано в этих примерах:

  • rand.Int() вызывает функцию, возвращающую случайное целое число.
  • rand.Intn() вызывает функцию, возвращающую случайный элемент от 0 до заданного числа.

Создадим цикл for, показывающий, как мы вызываем функцию пакета math/rand в нашей программе random.go:

random.go
package main

import "math/rand"

func main() {
  for i := 0; i < 10; i++ {
    println(rand.Intn(25))
  }
}

Вначале программа импортирует пакет math/rand в третьей строке, а затем переходит к циклу for, который выполняется 10 раз. В этом цикле программа выводит случайное целое число в диапазоне от 0 до 25. Целое число 25 передается функции rand.Intn() как параметр.

При запуске программы с помощью команды go run random.go мы получаем 10 случайных чисел. Поскольку это случайные числа, они скорее всего будут разными при каждом запуске программы. Результат будет выглядеть примерно так:

Output
6 12 22 9 6 18 0 15 6 0

Выводимые целые числа никогда не будут меньше 0 или больше 24.

При импорте нескольких пакетов вы можете использовать () для создания блока. Используя блоки, вы можете не повторять ключевое слово import на каждой строчке. Так ваш код будет выглядеть лучше:

random.go

import (
  "fmt"
  "math/rand"
)

Чтобы использовать дополнительный пакет, мы можем отформатировать результаты и вывести итерацию генерирования каждого случайного числа во время цикла:

random.go
package main

import (
  "fmt"
  "math/rand"
)

func main() {
  for i := 0; i < 10; i++ {
    fmt.Printf("%d) %d\n", i, rand.Intn(25))
  }
}

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

Output
0) 6 1) 12 2) 22 3) 9 4) 6 5) 18 6) 0 7) 15 8) 6 9) 0

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

Установка пакетов

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

Цепочка инструментов Go содержит команду go get. Эта команда позволяет устанавливать сторонние пакеты в локальную среду разработки и использовать их в вашей программе.

При использовании go get для установки сторонних пакетов часто используется канонический путь пакета. Это может быть путь к публичному проекту, размещенному в таком хранилище кода, как GitHub. Если вы захотите импортировать пакет flect, вы используете полный канонический путь:

  • go get github.com/gobuffalo/flect

Инструмент go get найдет пакет на GitHub и установит его в каталог $GOPATH.

В этом примере код будет устанавливаться в следующий каталог:

$GOPATH/src/github.com/gobuffalo/flect

Авторы часто обновляют пакеты, устраняя ошибки и добавляя новые возможности. В этом случае вам нужно использовать последнюю версию пакета для применения новых функций или устранения ошибок. Для обновления пакета вы можете использовать флаг -u с командой go get:

  • go get -u github.com/gobuffalo/flect

Эта команда также установит пакет в Go, если он отсутствует в локальной среде. Если пакет уже установлен, Go попытается обновить его до последней версии.

Команда go get всегда получает последнюю доступную версию пакета. Однако возможны обновления предыдущих версий пакета, которые все равно новее используемых, и поэтому программу будет полезно обновить. Чтобы получить определенную версию пакета, вам потребуется инструмент для управления пакетами, например Go Modules.

В версии Go 1.11 модули Go используются для определения версии пакета, которую вы хотите импортировать. В настоящей статье мы не рассматриваем тему управления пакетами, но вы можете прочитать об этом на странице Go Modules на GitHub.

Присвоение имен импортируемым пакетам

Вы можете изменить имя пакета, если у вас уже есть локальный пакет с тем же именем, что и у используемого стороннего пакета. В этом случае лучше всего присвоить псевдоним импортируемому пакету. Вы можете изменять имена пакетов и их функций Go посредством указания псевдонима перед именем импортируемого пакета.

Данное выражение выглядит следующим образом:

import another_name "package"

В этом примере мы изменяем имя пакета fmt в файле программы random.go. Мы изменим имя пакета fmt на f для сокращения. Измененная программа будет выглядеть следующим образом:

random.go
package main

import (
 f "fmt"
  "math/rand"
)

func main() {
  for i := 0; i < 10; i++ {
    f.Printf("%d) %d\n", i, rand.Intn(25))
  }
}

Теперь внутри программы мы ссылаемся на функцию Printf как на f.Printf, а не на fmt.Printf.

В других языках изменение имен пакетов поощряется для упрощения их использования в программе, в Go дела обстоят иначе. Например, изменение имени пакета fmt на f не будет соответствовать указаниям руководства по стилю.

При переименовании импортируемых файлов во избежание конфликта имен следует переименовывать наиболее локальные или относящиеся к конкретным проектам импортируемые пакеты. Например, если у вас имеется локальный пакет с именем strings, и вы хотите импортировать системный пакет с именем strings, лучше переименовать локальный пакет, а не системный. По возможности конфликта имен следует избегать.

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

Форматирование при импорте

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

В большинстве редакторов импортируемые файлы форматируются автоматически. Также вы можете настроить редактор для использования goimports. Использование goimports в редакторе считается стандартной практикой, поскольку поддерживать порядок сортировки импортируемых пакетов вручную сложно, и при этом возможны ошибки. Кроме того, в случае изменения стиля goimports также обновляется с учетом этих изменений. Благодаря этому все, кто работает над кодом, будут применять единый стиль импортируемых блоков.

Здесь показано, как может выглядеть блок импорта до форматирования:

import (
  "fmt"
  "os"
  "github.com/digital/ocean/godo"
  "github.com/sammy/foo"
  "math/rand"
  "github.com/sammy/bar"
)

Запуск инструмента goimport (который также запускается при сохранении файлов в большинстве редакторов, где есть этот инструмент) изменит формат следующим образом:

import (
  "fmt"
  "math/rand"
  "os"

  "github.com/sammy/foo"
  "github.com/sammy/bar"

  "github.com/digital/ocean/godo"
)

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

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

Заключение

Импорт пакетов позволяет нам вызывать функции, которые не встроены в Go. Некоторые пакеты являются частью стандартной библиотеки, входящей в комплектацию Go, а некоторые нужно устанавливать с помощью инструмента go get.

Использование пакетов делает программу более функциональной и надежной, поскольку мы используем существующий код. Также мы можем создавать собственные пакеты для себя и других программистов и использовать их в будущих программах.

Creative Commons License