golang变量做用域问题-避免使用全局变量

最近遇到了一个变量做用域的问题,一个比较低级的问题,可能做为一个熟手不该该犯这样的低级错误,可是golang的语法特色可能让你稍微不注意就踩坑,嘿嘿。golang

变量做用域

全局变量的做用域是整个包,局部变量的做用域是该变量所在的花括号内,这是一个很基础的问题。咱们一般会使用golang的一个语法糖:=来给变量赋值,这种方式能够节省掉咱们定义变量的代码,让代码变的更加简洁,可是若是你定义了一个全局变量,又不当心用:=来给它赋值,就会出现一些问题。函数

问题

看下面的代码,定义了一个全局变量t,我想在init()中给他赋值为2,而后在main中使用它。code

var t int

func init() {
    t, err := strconv.Atoi("2")
    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println("init:", t)
}

func main() {
    fmt.Println("main:", t)
}

输出:作用域

init: 2
main: 0

执行以后,在init和main中打印出了不同的数字,为何会不同呢,可能你仔细一看就知道缘由了。很简单,init中的t是用:=生成的,因此t是局部变量,在init函数中覆盖了全局变量t。全局变量t并无被赋值,它仍是原来的0值。it

我本想在init中给全局变量t赋值的,却不当心用:=建立了一个局部变量致使全局变量t没有赋值成功,犯了一个低级错误。基础

解决

知道缘由以后就容易解决了,我不使用:=就能够了。代码以下:变量

var t int

func init() {
    var err error
    t, err = strconv.Atoi("2")
    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println("init:", t)
}

func main() {
    fmt.Println("main:", t)
}

输出:语法

init: 2
main: 2

没有使用:=以后,init中的t就是全局变量t,给全局变量t赋值为2,main中天然输出的就是2,实现了我最初的目的。error

思考

这个问题很简单很低级,可是可能一个golang熟手,在代码远比demo要复杂的多的实际项目中,不经意间就可能会犯下这样的错误。demo

这个问题很难保证说下次必定不会出现的,除非你完全不用全局变量或者完全不用:=这样的语法糖。个人建议是这样:

  • 尽可能少的使用全局变量。
  • 尽可能少的使用:=语法糖。
  • 使用:=的时候要确保左值没有被定义过。
相关文章
相关标签/搜索