MySQL - invalid memory address or nil pointer dereference【Go】
複数の関数で、DBコネクションを使い回す場合には、注意が必要です。
dbだけでなく、sql.Open()の返り値に含まれるerrもpackageグローバルに定義して、
sql.Open()の返り値のアサインは「:=」ではなく、「=」を使用します。
var db *sql.DB var err error // *sql.DBだけでなく、errもpackageグローバルに定義する func main() { db, err = sql.Open("mysql", "root:password@/database-name") // errをグローバルに定義せず、「:=」を使うとinvalidエラーになる check(err) defer db.Close() ... http.HandleFunc("/read", read) http.Handle("/favicon.ico", http.NotFoundHandler()) http.ListenAndServe(":8080", nil) } func read(w http.ResponseWriter, req *http.Request) { rows, err := db.Query(`SELECT name FROM sample;`) // errをグローバルに定義せずsql.Open()の返り値のアサインに「:=」を使うと、ここでinvalidエラーになる check(err) defer rows.Close() ... }
errをグローバルに定義せず、sql.Open()の返り値のアサインを「:=」にすると、
read()のdb.Query()が実行された時、invalid memory address or nil pointer dereferenceエラーが発生します。
dbが新たに作成されて、それはsql.Open()の返り値を格納したものではないからです。