前两天很荣幸的踩到golang一个坑,可有意思了,记录一下
老代码
var conn *gorm.DB
func Init() error {
...
conn, err := gorm.Open(mysql.Open(mdbConf.DSN), &gorm.Config{})
...
}
func GetMDBClient() *gorm.DB {
return conn
}
复制代码
这部分代码,写的好有道理,建一个全局变量,然后在Init()函数中初始化你的db连接,最后通过GetMDBClient()函数获取db连接在其他部分进行操作。自己写的代码自己会越想越觉得合情合理、无可挑剔...然后服务它还是跑不起来,可刺激了。后边用单步调试+逐步逼近,打出来log告诉我conn为nil。可是明明有初始化啊!后边发现conn, err :=建立的是一个Init局部变量conn,然后把这个局部变量进行赋值,全局变量conn它还是个空指针...
所以应该修改一下
新代码
var conn *gorm.DB
func Init() error {
var err error
...
conn, err = gorm.Open(mysql.Open(mdbConf.DSN), &gorm.Config{})
...
}
func GetMDBClient() *gorm.DB {
return conn
}
复制代码
这样你的全局变量conn就能被正常赋值了
总结
golang的全局变量的使用一定要谨慎,不要一不小心成为局部变量赋值,它没有类似于Python的显式关键字global的提示。所以写的时候要注意这一点,不要整的赋值不成功