这样为何会出现空指针的问题呢?那应该如何传递这个DB供其他包调用

空指针疑问

InitDB:

package common
import (
    "Learn/models"
    "fmt"
    "log"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var DB *gorm.DB
var err error

func InitDB() {
    user := "root"
    passwd := "123456.."
    host := "127.0.0.1"
    port := "3306"
    databases := "gorm"
    charset := "utf8mb4"
    parseTime := "True"
    loc := "local"

    DSN := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s&%s&%s", user, passwd, host, port, databases, charset, parseTime, loc)

    DB, err = gorm.Open(mysql.Open(DSN))
    if err != nil {
        log.Println("conn DB err :,", err)
    }

    DB.AutoMigrate(&models.User{})
}

func GetDB() *gorm.DB {
    return DB
}

IsPhoneExist 工具:

func IsPhoneExist(DB *gorm.DB, phone string) bool {
    var user models.User
    DB.Where("phone = ?", phone).First(&user)

    if user.ID != 0 {
        return true
    }
    return false
}

controllers.Register() 调用DB查询手机是否存在,不存在则注册。

func Register(ctx *gin.Context) {
    DB := common.GetDB()
    // 获取参数
    name := ctx.PostForm("name")
    phone := ctx.PostForm("phone")
    passwd := ctx.PostForm("passwd")

    // 数据验证
    if len(phone) != 11 || len(passwd) < 6 {
        ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "手机号必须为11位,密码长度必须大于6"})
        return
    }

    // 如果名字传入为空则生成一个名字
    if len(name) == 0 {
        name = utils.RandomString(10)
    }

    log.Println(name, phone, passwd)

    // 判断手机号是否存在
    if utils.IsPhoneExist(DB, phone) {
        ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "用户已存在"})
        return
    }

    // 创建用户
    //         加密密码
    hashPasswd, err := bcrypt.GenerateFromPassword([]byte(passwd), bcrypt.DefaultCost)
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "加密错误"})
    }
    newUser := models.User{
        Name:   name,
        Phone:  phone,
        Passwd: string(hashPasswd),
    }

    DB.Create(&newUser)
    token, _ := common.ReleaseToken(models.User{})
    ctx.JSON(http.StatusOK, gin.H{"code": 200, "msg": "注册成功", "token": token})
}

完整err:

2022/12/28 15:40:29 /Users/tom/go/src/Learn/utils/utils.go:26 record not found
[2.892ms] [rows:0] SELECT * FROM `users` WHERE phone = '13888888888' AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT 1


2022/12/28 15:40:29 [Recovery] 2022/12/28 - 15:40:29 panic recovered:
POST /api/auth/register HTTP/1.1
Host: localhost
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 389
Content-Type: multipart/form-data; boundary=--------------------------224365142045323582604800
Postman-Token: 308fe9c8-ce3c-4c01-b0ad-b852b661e3f1
User-Agent: PostmanRuntime/7.29.2


runtime error: invalid memory address or nil pointer dereference
/usr/local/Cellar/go/1.18.4/libexec/src/runtime/panic.go:220 (0x1049f95)
        panicmem: panic(memoryError)
/usr/local/Cellar/go/1.18.4/libexec/src/runtime/signal_unix.go:818 (0x1049f65)
        sigpanic: panicmem()
/Users/tom/go/src/Learn/utils/utils.go:28 (0x1349a85)
        IsPhoneExist: if user.ID != 0 {
/Users/tom/go/src/Learn/controllers/userController.go:35 (0x155beb5)
        Register: if utils.IsPhoneExist(DB, phone) {
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x1550761)
        (*Context).Next: c.handlers[c.index](c)
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/recovery.go:101 (0x155074c)
        CustomRecoveryWithWriter.func1: c.Next()
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x154f846)
        (*Context).Next: c.handlers[c.index](c)
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/logger.go:240 (0x154f829)
        LoggerWithConfig.func1: c.Next()
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:173 (0x154e910)
        (*Context).Next: c.handlers[c.index](c)
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/gin.go:616 (0x154e578)
        (*Engine).handleHTTPRequest: c.Next()
/Users/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.2/gin.go:572 (0x154e0bc)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/Cellar/go/1.18.4/libexec/src/net/http/server.go:2916 (0x13a4cfa)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/Cellar/go/1.18.4/libexec/src/net/http/server.go:1966 (0x139fcf6)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/Cellar/go/1.18.4/libexec/src/runtime/asm_amd64.s:1571 (0x1064600)
        goexit: BYTE    $0x90   // NOP

[GIN] 2022/12/28 - 15:40:29 | 500 |    7.569688ms |             ::1 | POST     "/api/auth/register"
最佳答案
result := DB.Where("phone = ?", phone).First(&user)

if result.Error == nil {
    return true
}
2年前 评论
讨论数量: 5
野生菌

file

2年前 评论
Scrooge (楼主) 2年前
result := DB.Where("phone = ?", phone).First(&user)

if result.Error == nil {
    return true
}
2年前 评论

你的models.User应该是嵌套的 *gorm.Model 吧

2年前 评论
Scrooge (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!