我是初次接触lang的人,到目前为止我很喜欢它,但是当我运行该应用程序时,我遇到了这个问题:

invalid memory address or nil pointer dereference

我应该怎么做才能解决这个问题?

这是主文件syntax.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

    import (
       "blog/models"
       "fmt"
       "net/http"
    )

    func main() {
       models.DbConn()

       http.HandleFunc("/books", postsIndex)
       http.ListenAndServe(":3000", nil)

    }
    func postsIndex(w http.ResponseWriter, r *http.Request) {
        if r.Method !="GET" {
            http.Error(w, http.StatusText(405), 405)
            return
        }
        bks, err := models.AllPosts()
        if err != nil {
            http.Error(w, http.StatusText(500), 500)
            return
        }
        for _, bk := range bks {
            fmt.Fprintf(w,"%s, %s", bk.Title, bk.Description)
        }
    }

这是数据库连接db.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package models

import (
   "fmt"
   "database/sql"
    _"github.com/go-sql-driver/mysql"
   "log"
)
var db *sql.DB
func DbConn() {
    db, err := sql.Open("mysql","root:@/posts")

    if err != nil {
        log.Fatal(err)
    }else {
        fmt.Printf("this is working")
    }
    defer db.Close()
}

这是获取帖子posts.go的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package models

type Post struct {

    Title  string
    Description string

}

func AllPosts() ([]*Post, error) {
    rows, err := db.Query("SELECT * FROM posts")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    bks := make([]*Post, 0)
    for rows.Next() {
        bk := new(Post)
        err := rows.Scan(&bk.Title, &bk.Description )
        if err != nil {
            return nil, err
        }
        bks = append(bks, bk)
    }
    if err = rows.Err(); err != nil {
        return nil, err
    }
    return bks, nil
}
  • 该错误将向您确切显示nil指针取消引用的位置。 代码在哪里?

如果您查看显示错误的控制台,我想它将显示类似posts.go:9的内容。 在那条线上,您正在尝试执行数据库查询,但是到那时,到数据库的连接已经关闭。

在您的db.go中,

1
db, err := sql.Open("mysql","root:@/posts")

该行为函数范围创建两个变量,并为其分配值。 在函数完成时,没有剩余的使用范围变量db,因此连接已关闭。 因为您已使用:=,所以已经创建了新变量,但尚未将其分配给var db *sql.DB

作为快速解决方案,您可以将DbConn方法的第一部分更改为

1
2
var err error
db, err = sql.Open("mysql","root@/posts")

我为错误类型为新的变量添加了一行,并且assign现在将值分配给现有变量,而不是创建新变量(=:=)