在gorm中遇到这个报错目前可能会有两种原因:
-
数据库链接失败
-
Find 或 First 方法传入的变量是空的,没有内存地址
当时遇到这个报错是因为我使用gorm的Find()方法
data := make([]*UserBasic, 20)
utils.DB.Find(&data)
那么有可能是因为&data得到的是空导致的报错,使用print大法打印后:
发现data是有值的:
遂:检查数据库连接情况
最终发现是因为之前已经定义过一个全局变量,但是我在函数内部对这个全局变量进行了声明并且赋值的操作,相当于创建了一个局部变量
var DB *gorm.DB
func test(){
DB, err := gorm.Open(mysql.Open(viper.GetString("mysql.dns")), &gorm.Config{})
}
最终使用 DB.Find(&data)时,全局变量DB实际上是没有被赋值的。所以会导致报错的出现。
解决方法:
1、连接数据库时,将 := 改为 =
2、err的处理可以使用_忽略 或者创建全局变量 err进行处理
修改之后的代码:
var (
DB *gorm.DB
err error
)
func InitMySQL() *gorm.DB {
// 这里有一个坑,使用 :=赋值后,全局变量DB将被当前函数的DB替换为局部变量
//DB, err := gorm.Open(mysql.Open(viper.GetString("mysql.dns")), &gorm.Config{})
DB, err = gorm.Open(mysql.Open(viper.GetString("mysql.dns")), &gorm.Config{})
if err != nil {
fmt.Println("连接数据库失败", err)
} else {
fmt.Printf("数据库连接成功: %v", DB)
}
return DB
}
代码中如有不对或者可以优化的地方,欢迎指正,感激不尽。
总结:invalid memory address or nil pointer dereference 解决思路
一、数据库对象为空(网络问题、连接参数问题、全局变量问题...)
二、Find 或 First 方法传入的变量是空的,没有内存地址
去年年初公司进行新产品的研发,技术方面使用Golang进行产品移动端服务的开发,因为我主要是做Python,接到这个需求后也是磕磕绊绊,遇到不少问题,现在终于有时间记录下来。给新入门的同学做做铺垫少走些弯路,想到哪里就写到哪里吧!