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

前端 未结 4 1128
梦如初夏
梦如初夏 2020-11-30 17:31

I saw this example from sqlite3 on GitHub :

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


        
相关标签:
4条回答
  • 2020-11-30 17:43

    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) }
    
    0 讨论(0)
  • 2020-11-30 17:51

    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.

    0 讨论(0)
  • 2020-11-30 17:56

    Short answer:

    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")
    
    0 讨论(0)
  • 2020-11-30 18:03

    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.

    0 讨论(0)
提交回复
热议问题