登录
首页 >  Golang >  Go问答

如何解决 gorm Create() 出现“无效内存地址或 nil 指针取消引用”的恐慌?

来源:stackoverflow

时间:2024-02-09 10:09:25 197浏览 收藏

最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《如何解决 gorm Create() 出现“无效内存地址或 nil 指针取消引用”的恐慌?》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~

问题内容

我不知道如何解决这个恐慌,因为我在 go 方面确实是新手,特别是在指针方面,所以请耐心等待。我跟踪了恐慌消息,发现恐慌位于我的存储库包中的 gorm create() 中。

这是我的数据库连接

var (
    instance *gorm.db
)

func connect() {
    if err := godotenv.load(); err != nil {
        panic(err.error())
    }

    dbuser := os.getenv("db_username")
    dbpass := os.getenv("db_password")
    dbhost := os.getenv("db_host")
    dbname := os.getenv("db_name")

    dsn := fmt.sprintf("%s:%s@tcp(%s:3303)/%s?charset=utf8mb4&parsetime=true&loc=local", dbuser, dbpass, dbhost, dbname)
    db, err := gorm.open(mysql.open(dsn), &gorm.config{
        logger: logger.default.logmode(logger.info),
    })

    if err != nil {
        panic("error connecting database : " + err.error())
    }

    instance = db
}

func closedb() {
    conn, err := instance.db()
    if err != nil {
        panic("error closing database : " + err.error())
    }

    conn.close()
}

我的身份验证存储库

type authrepository interface {
    create(user *entity.user) *entity.user
}

type authconnection struct {
    db *gorm.db
}

func newauthrepository(db *gorm.db) authrepository {
    return &authconnection{db}
}

func (c *authconnection) create(user *entity.user) *entity.user {
    newpassword, err := hashpassword(user)
    if err != nil {
        return nil
    }

    user.password = newpassword
    result := c.db.create(user)
    if result == nil {
        return nil
    }

    return user

}

我的使用身份验证存储库的身份验证服务

var authrepository = repository.newauthrepository(database.instance)

type authservice struct {
    repository repository.authrepository
}

func (s *authservice) register(user *entity.user) (*entity.user, error) {
    newuser := s.repository.create(user)
    if newuser == nil {
        return nil, errors.new("failed registering user")
    }

    return newuser, nil
}

func newauthservice() *authservice {
    return &authservice{
        repository: authrepository,
    }
}

最后一个,我的身份验证控制器

var (
    authservice = service.newauthservice()
)

func registeruser(c *gin.context) {
    var user entity.user

    if err := c.shouldbindjson(&user); err != nil {
        handler.builderrorresponse(c, err)
        return
    }

    record, err := authservice.register(&user)
    if err != nil {
        handler.builderrorresponse(c, err)
        return
    }

    handler.buildcreatedresponse(c, record)
}

然后就报错了

runtime error: invalid memory address or nil pointer dereference
/usr/lib/golang/src/runtime/panic.go:212 (0x435eda)
        panicmem: panic(memoryError)
/usr/lib/golang/src/runtime/signal_unix.go:734 (0x44e892)
        sigpanic: panicmem()
/home/thoriqadillah/Development/Golang/pkg/mod/gorm.io/[email protected]/finisher_api.go:18 (0x5d9226)
        (*DB).Create: if db.CreateBatchSize > 0 {
/home/thoriqadillah/Development/Golang/src/jwt/repository/auth_repository.go:28 (0xa19d04)
        (*authConnection).Create: result := c.db.Create(user)
/home/thoriqadillah/Development/Golang/src/jwt/service/auth_service.go:18 (0xa19ee1)
        (*AuthService).Register: newUser := s.Repository.Create(user)
/home/thoriqadillah/Development/Golang/src/jwt/controller/auth_controller.go:22 (0xa1a0ae)
        RegisterUser: record, err := authService.Register(&user)
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/context.go:173 (0x9d9e39)
        (*Context).Next: c.handlers[c.index](c)
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/recovery.go:101 (0x9d9e20)
        CustomRecoveryWithWriter.func1: c.Next()
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/context.go:173 (0x9d9013)
        (*Context).Next: c.handlers[c.index](c)
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:240 (0x9d8fd2)
        LoggerWithConfig.func1: c.Next()
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/context.go:173 (0x9cedcf)
        (*Context).Next: c.handlers[c.index](c)
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:616 (0x9cedb5)
        (*Engine).handleHTTPRequest: c.Next()
/home/thoriqadillah/Development/Golang/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:572 (0x9ce879)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/lib/golang/src/net/http/server.go:2868 (0x7d7582)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/lib/golang/src/net/http/server.go:1933 (0x7d29ac)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/lib/golang/src/runtime/asm_amd64.s:1371 (0x46df60)
        goexit: BYTE    $0x90   // NOP

我假设错误来自 gorm create()。我尝试使用 fmt.println(user)fmt.println(&user)fmt.println(*user)fmt.println(&user) 在函数内打印 auth 存储库中的 fmt.println(&user) 参数来调试它 给出内存地址。但即使我用 create(&user) 更改 create(user) 它仍然不起作用。我尝试直接在控制器中使用 database.instance.create(&user) 中的 gorm 并且它有效,但我想学习使我的代码有点模块化


正确答案


实际上,您在字符串中遇到了错误:

db, err := gorm.open(mysql.open(dsn), &gorm.config{

由于运算符:=
go 创建一个新的局部变量 db 并使用它代替全局变量。
要解决此问题,只需将此行更改为:

var err error
db, err = gorm.open(mysql.open(dsn), &gorm.config{

或者,就您而言,对于这个:

var err error
Instance, err = gorm.Open(mysql.Open(dsn), &gorm.Config{

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《如何解决 gorm Create() 出现“无效内存地址或 nil 指针取消引用”的恐慌?》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>