Go编程语言规范指出:“要仅为其副作用(初始化)导入包,请使用空白标识符作为显式包名。”
例如:
import _ "foo/bar"
我很难想象这个结构的用例。 Usage of the `import` statement接受的答案提到了一个用例,其中可以加载数据库驱动程序,而不需要导入程序使用该程序包的任何导出函数,但它忽略了读者想象的细节。
是否有现实生活中的例子(包含代码片段和解释)来说明这个用例?
答案 0 :(得分:16)
我写的是image scaler。我希望它能够以不同的格式读取图像,例如 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"
答案 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"
)