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

Вступление

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

Этот учебник проведет вас через установку, импорт и псевдонимы пакетов.

Стандартные библиотечные пакеты

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

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

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

random.go

import "math/rand"

Когда мы импортируем пакет, мы делаем его доступным в нашей текущей программе как отдельное пространство имен. Это означает, что нам придется ссылаться на функцию вdot notation, как на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 случайных целых чисел. Поскольку они случайные, вы, вероятно, будете получать разные целые числа при каждом запуске программы. Вывод будет выглядеть примерно так:

Output6
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))
  }
}

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

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

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

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

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

Цепочка инструментов 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 всегда получает последнюю доступную версию пакета. Однако могут быть обновления предыдущих версий пакета, которые все еще новее, чем вы используете, и их было бы полезно обновить в вашей программе. Чтобы получить эту конкретную версию пакета, вам нужно будет использовать инструментPackage Management, напримерGo Modules.

Начиная с версии Go 1.11, модули Go используются для управления тем, какую версию пакета вы хотите импортировать. Тема управления пакетами выходит за рамки этой статьи, но вы можете прочитать об этом большеon the Go Modules GitHub page.

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

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

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

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))
  }
}

Теперь в программе мы называем функциюPrintff.Printf, а неfmt.Printf.

В то время как другие языки предпочитают создавать псевдонимы для удобства использования в дальнейшем в программе, Go этого не делает. Например, наложение пакетаfmt наf несовместимо сstyle guide.

При переименовании импорта, чтобы избежать конфликта имен, вы должны стремиться переименовать наиболее локальный или специфичный для проекта импорт. Например, если у вас есть пакетlocal с именемstrings, и вам также необходимо импортировать пакетsystem с именем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.

Использование пакетов позволяет нам сделать наши программы более надежными и мощными, поскольку мы используем существующий код. Мы также можем использоватьcreate our own packages для себя и других программистов в будущих программах.