Поиск…
Инициатизация пакетов
Пакет может иметь методы init
которые запускаются только один раз перед main.
package usefull
func init() {
// init code
}
Если вы просто хотите запустить инициализацию пакета без ссылки на что-либо из него, используйте следующее выражение импорта.
import _ "usefull"
Управление зависимостями пакетов
Общим способом загрузки зависимостей Go является команда go get <package>
, которая сохранит пакет в глобальном / общем $GOPATH/src
. Это означает, что одна версия каждого пакета будет связана с каждым проектом, который включает его как зависимость. Это также означает, что когда новые разработчики развертывают ваш проект, они будут go get
последнюю версию каждой зависимости.
Однако вы можете поддерживать целостность среды сборки, присоединяя все зависимости проекта к каталогу vendor/
. Сохранение зависимостей поставщиков, переданных вместе с репозиторием вашего проекта, позволяет выполнять управление версиями на основе каждого проекта и обеспечивать согласованную среду для вашей сборки.
Это будет выглядеть структура вашего проекта:
$GOPATH/src/
├── github.com/username/project/
| ├── main.go
| ├── vendor/
| | ├── github.com/pkg/errors
| | ├── github.com/gorilla/mux
Использование разных названий пакетов и папок
Прекрасно использовать имя пакета, отличное от имени папки. Если мы это сделаем, нам все равно придется импортировать пакет на основе структуры каталогов, но после импорта мы должны ссылаться на него по имени, которое мы использовали в предложении пакета.
Например, если у вас есть папка $GOPATH/src/mypck
, и в ней есть файл a.go
:
package apple
const Pi = 3.14
Использование этого пакета:
package main
import (
"mypck"
"fmt"
)
func main() {
fmt.Println(apple.Pi)
}
Несмотря на то, что это работает, у вас должна быть веская причина отклонить имя пакета от имени папки (или это может стать источником непонимания и путаницы).
Какая польза от этого?
Просто. Имя пакета - идентификатор Go:
identifier = letter { letter | unicode_digit } .
Это позволяет использовать символы Юникода в идентификаторах, например, αβ
является допустимым идентификатором в Go. Имена файлов и файлов не обрабатываются Go, а операционной системой, а разные файловые системы имеют разные ограничения. На самом деле существует множество файловых систем, которые не позволят всем действительным идентификаторам Go в качестве имен папок, поэтому вы не сможете назвать свои пакеты, что в противном случае разрешал бы язык.
Имея возможность использовать разные имена пакетов, чем их содержащие папки, у вас есть возможность действительно назвать свои пакеты, что позволяет спецификация языка, независимо от базовой операционной и файловой системы.
Импорт пакетов
Вы можете импортировать один пакет с инструкцией:
import "path/to/package"
или группировать несколько импортных товаров вместе:
import (
"path/to/package1"
"path/to/package2"
)
Это будет выглядеть в соответствующих путях import
внутри файлов $GOPATH
для .go
и позволяет вам обращаться к экспортированным именам через packagename.AnyExportedName
. packagename.AnyExportedName
.
Вы также можете получить доступ к локальным пакетам внутри текущей папки, предварительно поместив пакеты с ./
. В проекте со структурой вроде этого:
project
├── src
│ ├── package1
│ │ └── file1.go
│ └── package2
│ └── file2.go
└── main.go
Вы можете вызвать это в main.go
, чтобы импортировать код в file1.go
и file2.go
:
import (
"./src/package1"
"./src/package2"
)
Поскольку имена пакетов могут сталкиваться в разных библиотеках, вы можете захотеть присвоить одному пакету новое имя. Вы можете сделать это, предварительно указав свой import-statement на имя, которое хотите использовать.
import (
"fmt" //fmt from the standardlibrary
tfmt "some/thirdparty/fmt" //fmt from some other library
)
Это позволяет вам получить доступ к предыдущему пакету fmt
с помощью fmt.*
И последнего пакета fmt
с помощью tfmt.*
.
Вы также можете импортировать пакет в собственное пространство имен, чтобы вы могли ссылаться на экспортированные имена без package.
префикс с использованием одной точки в виде псевдонима:
import (
. "fmt"
)
Выше пример импортирует fmt
в глобальное пространство имен и позволяет вызывать, например, Printf
напрямую: Игровая площадка
Если вы импортируете пакет, но не используете его экспортированные имена, компилятор Go распечатает сообщение об ошибке. Чтобы обойти это, вы можете установить псевдоним на символ подчеркивания:
import (
_ "fmt"
)
Это может быть полезно, если вы не получаете доступ к этому пакету напрямую, но ему нужно запустить его функции init
.
Замечания:
Поскольку имена пакетов основаны на структуре папок, любые изменения в именах папок и ссылках на импорт (в том числе чувствительность к регистру) вызовут ошибку времени компиляции «случайное импортное столкновение» в Linux и OS-X, что трудно отследить и исправление (сообщение об ошибке является загадочным для простых смертных, поскольку оно пытается передать противоположное - что сравнение не удалось из-за чувствительности к регистру).
ex: путь / to / Package1 "против" path / to / package1 "
Пример: https://github.com/akamai-open/AkamaiOPEN-edgegrid-golang/issues/2