Вариант использования для импорта с пустым идентификатором в golang
В спецификации языка программирования Go указано: "Чтобы импортировать пакет исключительно для его побочных эффектов (инициализация), используйте пустой идентификатор как явное имя пакета".
Например:
import _ "foo/bar"
Мне трудно представить себе пример использования этой конструкции. В принятом ответе на использование инструкции "import" упоминается пример использования драйвера базы данных, который не может быть загружен без необходимости использования какой-либо экспортированной функции этого пакета, но он не учитывает детали для воображения читателя.
Существуют ли примеры реальной жизни (с фрагментами кода и пояснениями), которые иллюстрируют этот вариант использования?
Ответы
Ответ 1
Я писал масштабирующее устройство. Я хотел, чтобы он мог читать изображения в разных форматах, таких как JPEG, PNG и GIF, и выводить их в формате JPEG.
Поэтому в дополнение к пакетам image
и image/jpeg
мне также пришлось импортировать image/png
и image/gif
только для регистрации их соответствующих декодеров.
Если бы я не импортировал их, сканер мог бы только читать изображения JPEG.
package main
import(
"image"
"image/jpeg" // I wanted to export the images as JPEG
_ "image/png"
_ "image/gif"
)
// ...
Соответствующая документация из пакета image
:
Для декодирования любого конкретного формата изображения требуется предварительная регистрация функции декодера. Регистрация обычно является автоматическим в качестве побочного эффекта инициализации этого пакета формата, так что для декодирования изображения PNG достаточно иметь:
import _ "image/png"
Ответ 2
Это происходит из-за функции init
каждый исходный файл может определять свою собственную функцию init
niladic для настройки любого состояния. (На самом деле каждый файл может иметь несколько функций init
.)
И, наконец, означает, наконец: init
вызывается после того, как все объявления переменных в пакете оценили их инициализаторы, и они оцениваются только после того, как все импортированные пакеты были инициализированы.
Вот как работает go-sqlite3, упомянутое в " Что подчеркивает перед выражением импорта в Go ".
func init() {
sql.Register("sqlite3", &SQLiteDriver{})
}
У вас есть другой пример в разделе " Понимание пакетов Golang ":
В некоторых контекстах нам может понадобиться импортировать пакет только для вызова его метода init
, где нам не нужно вызывать другие методы пакета.
Если мы импортируем пакет и не используем идентификатор пакета в программе, Go компилятор покажет ошибку.
В такой ситуации мы можем использовать пустой идентификатор (_
) в качестве имени псевдонима пакета, поэтому компилятор игнорирует ошибку, не используя идентификатор пакета, но все равно будет вызывать функцию init.
Ответ 3
Вариант использования - это то, что вы хотите - это только функция init
выполняющая некоторую инициализацию (например, регистрируясь, чтобы вам не приходилось их явно называть).
Примером является регистрация некоторых драйверов базы данных:
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)