在go-sqlite3的代码中:
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"log"
"os"
)
import语句中的下划线是什么意思?
在go-sqlite3的代码中:
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"log"
"os"
)
import语句中的下划线是什么意思?
https://golang.org/doc/effective_go.html#blank
要么还在研究中,要么就是因为副作用而引进的。在这种情况下,我认为这是为了治疗副作用,正如医生所说。
这是为了只因为副作用而导入一个包。
Go规范:
如果只导入一个包的副作用(初始化),使用空白标识符作为显式的包名: 导入_ "lib/math"
在sqlite3
在go-sqlite3的情况下,下划线导入用于在init()函数中将sqlite3驱动程序注册为数据库驱动程序的副作用,而不导入任何其他函数:
sql.Register("sqlite3", &SQLiteDriver{})
一旦以这种方式注册,sqlite3就可以在你的代码中与标准库的sql接口一起使用,如示例所示:
db, err := sql.Open("sqlite3", "./foo.db")
虽然其他答案完全描述了它,但对于“Show me The Code”的人来说,这基本上意味着:创建包级别的变量并执行包的init函数。
以及(如果有的话)包级别变量的层次结构和包的init函数,该包已导入。
一个包在不被实际调用的情况下所能产生的唯一副作用是在它的init函数中创建包级变量(公共或私有)。
注意:在init函数之前运行一个函数是有技巧的。通过使用该函数初始化包级变量,我们可以为此使用包级变量。
func theVeryFirstFunction() int {
log.Println("theVeryFirstFunction")
return 6
}
var (
Num = theVeryFirstFunction()
)
func init() { log.Println("init", Num) }
Let's say you have an Animal package. And your main file wants to use that Animal package to call a method called Speak but there are many different types of animals and each animal implemented their own common Talk method. So let's say you want to call a method Speak implemented in the Animal's package which internally calls Talk method implemented in each of the animal's package. So in this case you just want to do an import _ "dog" which will actually call the init method defined inside the dog package which actually registers a Talk method with the Animal package which it too imports.
因为我是围棋新手,这个定义让我更清楚:
下划线是Go中的一个特殊字符,充当空容器。因为我们导入了一个包,但没有使用它,Go编译器会报错。为了避免这种情况,我们将该包的引用存储到_中,Go编译器将简单地忽略它。 当你想初始化一个包但又不使用它时,用下划线对一个包进行别名(它似乎什么都不做)是非常有用的。
Link