阿小信大人的头像
Talk is cheap. Show me the code. Linus Torvalds

Golang变量作用域踩坑记录2018-10-26 11:14

这是一篇记录实际应用中遇到的变量作用域问题,golang的学习资料中很多都提到过这个知识点,但是实际使用中还是不小心就忽略掉坑里了。

背景:打算封装一个gorm的初始化连接db的操作放在一个包里,通过调用这个初始化函数为包里面的全局变量var DB *gorm.DB 赋值来作为操作db的句柄

错误写法:

var DB *gorm.DB

func InitGormDB(engine, addr, name, username, password string) {

    var dsn string

    switch strings.ToLower(engine) {
    case "mysql":
        dsn = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local", username, password, addr, name)
    case "postgres":
        addr_ := strings.Split(addr, ":")
        dsn = fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s", addr_[0], addr_[1], username, name, password)
    case "sqlite3":
        dsn = name
    case "mssql":
        dsn = fmt.Sprintf("sqlserver://%s:%s@%s?database=%s", username, password, addr, name)
    }
    // be careful the var scope
    // use `:=` will declare a new local variable named DB, raise compile error of var declared and not used
    DB, err := gorm.Open(engine, dsn)
    if err != nil {
        log.Fatal(err)
    }
}

DB, err := gorm.Open(engine, dsn) 这一句使用的是 := 短变量声明语句,新声明了一个DBerr局部变量, golang中全局变量与局部变量名称可以相同,局部的DB会屏蔽全部的DB, 局部DB的赋值不代表全局的DB被赋值,他们是两个变量。 由于后面的代码没有使用这个局部的DB变量,所以编译时会报错DB declared and not used

所以要解决这个问题只需不要再声明新的局部变量即可,直接使用=进行赋值操作,修改如下:

var DB *gorm.DB

func InitGormDB(engine, addr, name, username, password string) {

    var dsn string
    var err error

    switch strings.ToLower(engine) {
    case "mysql":
        dsn = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local", username, password, addr, name)
    case "postgres":
        addr_ := strings.Split(addr, ":")
        dsn = fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=%s", addr_[0], addr_[1], username, name, password)
    case "sqlite3":
        dsn = name
    case "mssql":
        dsn = fmt.Sprintf("sqlserver://%s:%s@%s?database=%s", username, password, addr, name)
    }
    // var scope: use `:=` will declare a new local variable named DB, raise compile error of var not be used
    DB, err = gorm.Open(engine, dsn)
    if err != nil {
        log.Fatal(err)
    }
}

如果您觉得从我的分享中得到了帮助,并且希望我的博客持续发展下去,请点击支付宝捐赠,谢谢!

若非特别声明,文章均为阿小信的个人笔记,转载请注明出处。文章如有侵权内容,请联系我,我会及时删除。

#Golang#  
分享到:
阅读[775] 评论[0]

你可能也感兴趣的文章推荐

本文最近访客

网友54.*.*.87[火星]2019-06-27 06:10
网友123.*.*.105[北京]2019-06-27 06:09
网友46.*.*.143[火星]2019-06-27 06:05
网友46.*.*.197[德国]2019-06-27 05:57

发表评论