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