2014-09-30 85 views
1

當我運行我的Go代碼來查詢我的本地postgres數據庫時,我不斷收到此錯誤。轉:運行postgres查詢時出現無效的內存地址錯誤

錯誤:

panic serving [::1]:56708: runtime error: invalid memory address or nil pointer dereference 
goroutine 23 [running]: 
net/http.func·011() 
    /usr/local/go/src/pkg/net/http/server.go:1100 +0xb7 
runtime.panic(0x2ef0a0, 0x4d8ee4) 
    /usr/local/go/src/pkg/runtime/panic.c:248 +0x18d 
database/sql.(*DB).conn(0x0, 0x277a1, 0x0, 0x0) 
    /usr/local/go/src/pkg/database/sql/sql.go:625 +0x751 
database/sql.(*DB).Ping(0x0, 0x0, 0x0) 
    /usr/local/go/src/pkg/database/sql/sql.go:452 +0x39 
main.firstHandler(0x58e9a8, 0xc208052320, 0xc2080284e0) 
    /Users/Tommy/Documents/gocode/server/server.go:122 +0x35 
net/http.HandlerFunc.ServeHTTP(0x3c6be8, 0x58e9a8, 0xc208052320, 0xc2080284e0) 
    /usr/local/go/src/pkg/net/http/server.go:1235 +0x40 
github.com/gorilla/mux.(*Router).ServeHTTP(0xc2080186e0, 0x58e9a8, 0xc208052320, 0xc2080284e0) 
    /Users/Audrey/gocode/src/github.com/gorilla/mux/mux.go:98 +0x292 
net/http.(*ServeMux).ServeHTTP(0xc208022660, 0x58e9a8, 0xc208052320, 0xc2080284e0) 
    /usr/local/go/src/pkg/net/http/server.go:1511 +0x1a3 
net/http.serverHandler.ServeHTTP(0xc208004660, 0x58e9a8, 0xc208052320, 0xc2080284e0) 
    /usr/local/go/src/pkg/net/http/server.go:1673 +0x19f 
net/http.(*conn).serve(0xc208050500) 
    /usr/local/go/src/pkg/net/http/server.go:1174 +0xa7e 
created by net/http.(*Server).Serve 
    /usr/local/go/src/pkg/net/http/server.go:1721 +0x313 

轉到:

func firstHandler(w http.ResponseWriter, r *http.Request) { 
    err := db.Ping() 
    if err != nil { 
     log.Fatal(err) 
    } 
    rows, err := db.Query("SELECT id, created_at, updated_at FROM script WHERE updated_at = $1", 3) 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer rows.Close() 

    var created_at, updated_at, id int 
    for rows.Next() { 
     err := rows.Scan(&id, &created_at, &updated_at) 
     if err != nil { 
      log.Fatal(err) 
     } 
     fmt.Fprintf("%s %s %s", id, created_at, updated_at) 
    } 
} 

var r = mux.NewRouter() 
var db *sql.DB 

func main() { 
    db, err := sql.Open("postgres", "user=Tommy host=localhost dbname=dbgo sslmode=verify-full") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer db.Close() 

    r.HandleFunc("/ping", firstHandler) 

    http.Handle("/", r) 

    http.ListenAndServe(":8080", nil) 
} 

幫助。我究竟做錯了什麼?我也提到這個:https://gophercasts.io/lessons/4-postgres-basics

+0

棧板在哪裏?它應該指向你解除引用一個零指針的確切點。 – JimB 2014-09-30 16:00:44

+0

我已更新我的代碼。你的意思是?雖然我找不到確切的一點。 – user3918985 2014-09-30 16:05:18

+0

第42行是什麼?我沒有看到「ReadAllContent」函數。 – OneOfOne 2014-09-30 16:16:42

回答

8

其實,聲明與連接:

var db *sql.DB 

,但你打開一個連接:

db, err := sql.Open("postgres", "user=Tommy host=localhost dbname=dbgo sslmode=verify-full") 

注:=(它結合了變量聲明與賦值)。這實際上會影響全局數據庫變量的本地。連接已打開但分配給本地變量。所以全局數據庫變量的值是零。

當firstHandler函數被調用時,它的值仍然是零,這觸發了恐慌。

替換:= a =(並在之前聲明err對象)。

+0

或者,避免全局變量。 – dyoo 2014-09-30 20:00:06