用于在golang中导入空白标识符的用例

时间:2014-11-17 12:20:42

标签: go

Go编程语言规范指出:“要仅为其副作用(初始化)导入包,请使用空白标识符作为显式包名。”

例如:

import _ "foo/bar"

我很难想象这个结构的用例。 Usage of the `import` statement接受的答案提到了一个用例,其中可以加载数据库驱动程序,而不需要导入程序使用该程序包的任何导出函数,但它忽略了读者想象的细节。

是否有现实生活中的例子(包含代码片段和解释)来说明这个用例?

3 个答案:

答案 0 :(得分:16)

我写的是image scaler。我希望它能够以不同的格式读取图像,例如 JPEG PNG & GIF 并以 JPEG 输出。

因此,除imageimage/jpeg个软件包外,我还必须导入image/pngimage/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"

答案 1 :(得分:15)

这是因为 init function

  

每个源文件都可以定义自己的niladic init函数来设置所需的状态。 (实际上每个文件可以有多个init函数。)

     

最后意味着最终:在包中的所有变量声明都已经评估了它们的初始值设定项之后调用init,并且只有在初始化了所有导入的包之后才会对它们进行求值。

这就是“go-sqlite3”中提到的What does an underscore in front of an import statement mean in Go的工作原理。

func init() {
    sql.Register("sqlite3", &SQLiteDriver{})
}

Understanding Golang Packagese”中有另一个例子:

  

在某些情况下,我们可能只需要导入一个包来调用它的init方法,我们不需要调用包的其他方法。
  如果我们导入了一个包但未在程序中使用包标识符,Go编译器将显示错误
  在这种情况下,我们可以使用空标识符(_)作为包别名,因此编译器会忽略不使用包标识符的错误,但仍会调用init函数。

答案 2 :(得分:5)

一个用例就是当你想要的只是init function进行一些初始化时(例如注册自己以便你不必明确地调用它们)。

例子是some database drivers的注册地址:

import (
    "database/sql"
    _ "github.com/ziutek/mymysql/godrv"
)