前两天很荣幸的踩到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的提示。所以写的时候要注意这一点,不要整的赋值不成功