Пакеты в Go - Часть 2
В прошлой статье мы разобрали как можно создать пакет в golang, в этой давайте детальней разберемся как работать с импортировать другие пакеты и некоторые их особенности объявления.
Импорты
Оператор import
сообщает компилятору, где искать на диске, чтобы найти пакет, который вы хотите импортировать.
import "fmt"
Чтобы импортировать более одного пакета, вам необходимо заключить операторы импорта в блок импорта.
import (
"fmt"
"strings"
)
Пакеты находятся на диске на основе их относительного пути к каталогам, на которые ссылается GOPATH
. Если компилятор не может найти пакет, на который вы ссылаетесь в GOPATH
, вы получите сообщение об ошибке при попытке запустить или собрать вашу программу.
Удаленный импорт
Инструменты Go имеют встроенную поддержку для получения исходного кода из распределенных систем контроля версий (DVCS), таких как сайты совместного использования, такие как Github.
Например:
import "github.com/dgrijalva/jwt-go"
Когда импортированный путь содержит URL-адрес, инструмент Go можно использовать для получения пакета из DVCS и размещения кода внутри GOPATH
в месте, которое соответствует URL-адресу.
Именованный импорт
Пакеты с тем же именем можно импортировать с помощью именованного импорта.
package main
import (
"fmt"
myfmt "mylib/fmt"
)
func main() {
fmt.Println("Standard library")
myfmt.Println("My custom library")
}
Компилятор Go завершит сборку с ошибкой и выдаст ошибку всякий раз, когда вы импортируете пакет, который не используете.
Пустой идентификатор
Go не допускает неиспользуемых переменных. Любую неиспользуемую переменную можно заменить символом подчеркивания _
, известным как пустой идентификатор. Пустой импорт пакета используется, когда импортированный пакет не используется в текущей программе, но нам нужна функция инициализации в исходных файлах Go, принадлежащих этому пакету, которую можно вызвать, и инициализация переменных в этом пакете может быть выполнена правильно.
В качестве примера пакет mysql используется как пустой импорт из-за его побочного эффекта регистрации драйвера mysql в качестве драйвера базы данных в функции init() пакета mysql без импорта каких-либо других функций.
_ "github.com/go-sql-driver/mysql"
Init
Каждый пакет имеет возможность предоставлять не ограниченное количество функций init()
. Они автоматически выполняются перед вызовом функции main()
в пакете man.
Функция init()
аналогична функции main()
. Она не принимает никаких аргументов и ничего не возвращает. Go может поддерживать несколько функций init()
в одном файле. Они вызываются в соответствующем порядке объявления в файле.
package main
import "fmt"
func init() {
fmt.Println("init 1")
}
func init() {
fmt.Println("init 2")
}
func main() {
fmt.Println("main")
}
$ go run main.go
init 1
init 2
main
Эти init()
функции отлично подходят для настройки пакетов, инициализации переменных или выполнения любой другой начальной загрузки, которая может вам понадобиться перед запуском программы.
Примером этого являются драйверы базы данных. Они регистрируются в пакете SQL, когда их функция инициализации выполняется при запуске, потому что пакет SQL не может знать о драйверах, которые существуют при его компиляции. Давайте посмотрим на пример того, что может делать функция инициализации.
package postgres
import (
"database/sql"
)
func init() {
sql.Register("postgres", new(PostgresDriver))
}
Этот код находится внутри вашего воображаемого драйвера базы данных для базы данных PostgreSQL. Когда программа импортирует этот пакет, будет вызвана функция init, в результате чего драйвер базы данных будет зарегистрирован в пакете sql Go в качестве доступного драйвера.
Теперь мы можем указать методу sql.Open
использования этого драйвера.
package main
import (
"database/sql"
_ "https://github.com/goinaction/code/chapter3/dbdriver/postgres"
)
func main() {
sql.Open("postgres", "mydb")
}