web-dev-qa-db-ja.com

importステートメントの前にあるアンダースコアとはどういう意味ですか?

この例はGitHubsqlite3から

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

インポート文の前にあるアンダースコアが何を意味するのか見つけることができないようです。

172
Adrian

簡潔な答え:

副作用のみのためにパッケージをインポートするためです。

Go仕様 から:

副作用(初期化)のためだけにパッケージをインポートするには、空の識別子を明示的なパッケージ名として使用します。

import _ "lib/math"

Sqlite3で

go-sqlite の場合、アンダースコアインポートは、init()関数でsqlite3ドライバーをデータベースドライバーとして登録する副作用として、インポートせずに使用されます。その他の機能:

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

この方法で登録すると、次の例のように、コード内で標準ライブラリのsqlインターフェイスでsqlite3を使用できます。

db, err := sql.Open("sqlite3", "./foo.db")
181
Herman Schaaf

「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) }
23

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

それは進行中の作業か、副作用のためにインポートされたものです。この場合、ドキュメントで説明されているように、副作用のためだと思います。

15
jgritty