在这段代码 from go-sqlite3中:
import ( "database/sql" "fmt" _ "github.com/mattn/go-sqlite3" "log" "os" )
import语句中的下划线是什么意思?
import
https://golang.org/doc/effective_go.html#blank
要么还在研究中,要么就是因为副作用而引进的。在这种情况下,我认为这是为了治疗副作用,正如医生所说。
这是为了只因为副作用而导入一个包。
从Go规范:
如果只为了副作用(初始化)而导入一个包,可以使用空白标识符作为显式包名: import _ "lib/math"
如果只为了副作用(初始化)而导入一个包,可以使用空白标识符作为显式包名:
import _ "lib/math"
在go-sqlite3的情况下,下划线导入用于在init()函数中将sqlite3驱动程序注册为数据库驱动程序的副作用,而不导入任何其他函数:
init()
sqlite3
sql.Register("sqlite3", &SQLiteDriver{})
一旦以这种方式注册,sqlite3就可以在代码中与标准库的sql接口一起使用,如示例所示:
sql
db, err := sql.Open("sqlite3", "./foo.db")
而另一些回答则完全描述了它,因为“Show me The code”;对于人来说,这基本上意味着:创建包级变量并执行该包的init函数。
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方法。所以在这个例子中,你只需要导入_ "dog"它会调用在dog包中定义的init方法,它会在Animal包中注册一个Talk方法,它也会导入Animal包。
因为我是围棋新手,这个定义让我更清楚:
下划线是Go中的一个特殊字符,充当空容器。因为我们导入了一个包,但没有使用它,Go编译器会报错。为了避免这种情况,我们将该包的引用存储到_中,Go编译器将简单地忽略它。 当你想初始化一个包但不使用它时,用下划线对一个包进行别名似乎什么都不做,这是非常有用的
Link