Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does an underscore in front of an import statement mean?

Tags:

import

go

In this code from go-sqlite3:

import (
        "database/sql"
        "fmt"
        _ "github.com/mattn/go-sqlite3"
        "log"
        "os"
)

what does the underscore in the import statement mean?

like image 915
Adrian Avatar asked Jan 19 '14 17:01

Adrian


People also ask

What is in import statement?

An import statement tells the compiler the path of a class or the entire package. It is unlike “#include” in C++, which includes the entire code in the program. Import statement tells the compiler that we want to use a class (or classes) that is defined under a package.

Should not use dot imports?

Using dot imports is frowned upon as it removes the desirable property of being able to understand where a symbol comes from by just looking at it. Do not use dot imports. There are some very few reasonable use cases for dot imports. You're unlikely to run into them at the start of your Go career.


4 Answers

It's for importing a package solely for its side-effects.

From the Go Specification:

To import a package solely for its side-effects (initialization), use the blank identifier as explicit package name:

import _ "lib/math"

In sqlite3

In the case of go-sqlite3, the underscore import is used for the side-effect of registering the sqlite3 driver as a database driver in the init() function, without importing any other functions:

sql.Register("sqlite3", &SQLiteDriver{})

Once it's registered in this way, sqlite3 can be used with the standard library's sql interface in your code like in the example:

db, err := sql.Open("sqlite3", "./foo.db")
like image 79
Herman Schaaf Avatar answered Oct 04 '22 11:10

Herman Schaaf


While other answers described it completely, for "Show me The Code" people, this basically means: create package-level variables and execute the init function of that package.

And (if any) the hierarchy of package-level variables & init functions of packages that, this package has imported.

The only side effect that a package can make, without being actually called, is by creating package-level variables (public or private) and inside it's init function.

Note: There is a trick to run a function before even init function. We can use package-level variables for this by initializing them using that function.

func theVeryFirstFunction() int {
    log.Println("theVeryFirstFunction")
    return 6
}

var (
    Num = theVeryFirstFunction()
)

func init() { log.Println("init", Num) }
like image 27
Kaveh Shahbazian Avatar answered Oct 04 '22 12:10

Kaveh Shahbazian


https://golang.org/doc/effective_go.html#blank

It's either a work in progress, or imported for side effects. In this case, I believe it's for the side effects, as described in the doc.

like image 27
jgritty Avatar answered Oct 04 '22 12:10

jgritty


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.

like image 27
Ankur Kothari Avatar answered Oct 04 '22 12:10

Ankur Kothari