【发布时间】:2014-02-08 19:13:21
【问题描述】:
我看到this example from sqlite3 on GitHub:
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"log"
"os"
)
并且似乎无法找到 import 语句前面的下划线的含义。
【问题讨论】:
我看到this example from sqlite3 on GitHub:
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"log"
"os"
)
并且似乎无法找到 import 语句前面的下划线的含义。
【问题讨论】:
虽然其他答案完全描述了它,但对于“给我看代码”的人来说,这基本上意味着:创建包级变量并执行该包的 init 函数。
以及(如果有的话)包级变量的层次结构和此包已导入的包的init 函数。
一个包可以产生的唯一副作用,而不是被实际调用,是通过创建包级变量(公共或私有)并在其内部 init 函数。
注意:在 init 函数之前运行函数有一个技巧。我们可以为此使用包级变量,方法是使用该函数对其进行初始化。
func theVeryFirstFunction() int {
log.Println("theVeryFirstFunction")
return 6
}
var (
Num = theVeryFirstFunction()
)
func init() { log.Println("init", Num) }
【讨论】:
假设您有一个 Animal 包裹。并且您的主文件想要使用该 Animal 包来调用一个名为 Speak 的方法,但是有许多不同类型的动物,并且每种动物都实现了自己的通用 Talk 方法。因此,假设您要调用 Animal 包中实现的 Speak 方法,该方法在内部调用每个 Animal 包中实现的 Talk 方法。因此,在这种情况下,您只需执行一个 import _ "dog" ,它实际上会调用定义在 dog 包中的 init 方法,该方法实际上将 Talk 方法注册到它也导入的 Animal 包中。
【讨论】:
https://golang.org/doc/effective_go.html#blank
它要么是正在进行中的工作,要么是为了副作用而导入的。在这种情况下,我相信这是因为文档中描述的副作用。
【讨论】:
这是为了导入一个包,只是为了它的副作用。
要仅出于副作用(初始化)而导入包,请使用空白标识符作为显式包名称:
导入_“lib/math”
在go-sqlite3 的情况下,下划线导入用于将sqlite3 驱动程序注册为init() 函数中的数据库驱动程序的副作用,而不导入任何其他函数:
sql.Register("sqlite3", &SQLiteDriver{})
一旦以这种方式注册,sqlite3 就可以在您的代码中与标准库的sql 接口一起使用,如示例中所示:
db, err := sql.Open("sqlite3", "./foo.db")
【讨论】: