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

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

Этот мануал расскажет вам про установку, импортирование пакетов и псевдонимы.

Читайте также: Как писать Go-пакеты

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

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

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

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

import "math/rand"

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

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

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

Давайте создадим цикл for в программе random.go, чтобы затем вызывать функцию пакета math/rand:

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 случайных целых чисел (поскольку они случайные, вы, вероятно, получите совсем другой результат). Вывод будет выглядеть примерно так:

6
12
22
9
6
18
0
15
6
0

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

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

import (
"fmt"
"math/rand"
)

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

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

Теперь, запустив программу, вы получите:

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

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

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

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

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

import another_name "package"

Давайте изменим имя пакета fmt в программном файле random.go на f, чтобы сократить его. В результате программа будет выглядеть так:

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 этого не делает. Например, псевдоним f для пакета fmt не соответствует соглашениям по стилю.

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

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

Форматирование импортируемых пакетов

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

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

Вот как может выглядеть блок import до форматирования:

import (
"fmt"
"os"
"github.com/some/link/godo"
"github.com/somelink/foo"
"math/rand"
"github.com/somelink/bar"
)

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

import (
"fmt"
"math/rand"
"os"
"github.com/somelink/foo"
"github.com/somelink/bar"
"github.com/some/link/godo"
)

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

Теперь вы знаете, что goimports может правильно отформатировать все блоки import и предотвратить множество ошибок.

Заключение

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

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

Tags: ,