我是初次使用lang的人,到目前为止我很喜欢它,但是当我运行该应用程序时,我遇到了这个问题:
无效的内存地址或nil指针取消引用
我该如何解决该问题?
这是主文件syntax.go
:
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
:
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
的文件:
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
}
答案 0 :(得分:0)
如果您查看显示错误的控制台,我想它将显示类似posts.go:9
的内容。在那条线上,您正在尝试执行数据库查询,但是到那时,与数据库的连接已经关闭。
在您的db.go
中,有一行
db, err := sql.Open("mysql","root:@/posts")
该行为函数范围创建两个变量,并为其分配值。在函数完成时,没有任何东西使用范围变量db
,因此连接已关闭。因为您已经使用了:=
个新变量,所以尚未将其分配给var db *sql.DB
。
作为快速解决方案,您可以将DbConn方法的第一部分更改为
var err error
db, err = sql.Open("mysql", "root@/posts")
我为错误类型为新的变量添加了一行,现在assign将值分配给现有变量,而不是创建新变量(=
与:=
)