Go:运行postgres查询时出现无效的内存地址错误

时间:2014-09-30 15:58:07

标签: postgresql go

当我运行Go代码时,我不断收到此错误,该代码向我的本地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

1 个答案:

答案 0 :(得分:8)

实际上,您声明连接:

var db *sql.DB

但您打开连接:

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

注意:=(它将变量声明与赋值组合在一起)。这实际上会通过本地变量影响全局db变量。连接已打开,但已分配给局部变量。所以全局db变量的值是nil。

调用firstHandler函数时,其值仍为nil,从而触发恐慌。

将= =替换为a =(并在之前声明错误的对象)。