297

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?

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Adrian
  • 19,440
  • 34
  • 112
  • 219

5 Answers5

324

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")
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Herman Schaaf
  • 46,821
  • 21
  • 100
  • 139
63

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) }
Kaveh Shahbazian
  • 13,088
  • 13
  • 80
  • 139
23

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.

jgritty
  • 11,660
  • 3
  • 38
  • 60
  • 1
    Here's a link to the [Import for side effect](https://golang.org/doc/effective_go.html#blank_import) anchor on that page. It explains, "sometimes it is useful to import a package only for its side effects, without any explicit use", and "To import the package only for its side effects, rename the package to the blank identifier". – Luke Sheppard Jul 10 '19 at 21:17
6

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.

Ankur Kothari
  • 822
  • 9
  • 11
1

As I'm new in Go, this definition made it more clear:

Underscore is a special character in Go which acts as null container. Since we are importing a package but not using it, Go compiler will complain about it. To avoid that, we are storing reference of that package into _ and Go compiler will simply ignore it. Aliasing a package with an underscore which seems to do nothing is quite useful sometimes when you want to initialize a package but not use it.

Link

SeeSharp
  • 608
  • 1
  • 13
  • 21