zoukankan      html  css  js  c++  java
  • golang变量作用域问题-避免使用全局变量

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

    变量作用域

    全局变量的作用域是整个包,局部变量的作用域是该变量所在的花括号内,这是一个很基础的问题。我们通常会使用golang的一个语法糖:=来给变量赋值,这种方式可以节省掉我们定义变量的代码,让代码变的更加简洁,但是如果你定义了一个全局变量,又不小心用:=来给它赋值,就会出现一些问题。

    问题

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

    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值。

    我本想在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,实现了我最初的目的。

    思考

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

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

    • 尽量少的使用全局变量。
    • 尽量少的使用:=语法糖。
    • 使用:=的时候要确保左值没有被定义过。
  • 相关阅读:
    Visual C# 3.0 新特性概览
    一个C#睡前故事[翻译]
    ASP.NET User Control使用技巧一则
    Visual Studio 2005 调试器的新增功能
    .NET Framework 3.0新特性
    客户端提高WEB页面显示速度的方法
    VS.Net 2005中如何:使用“编辑并继续”
    如何在 VS 2005 里调试 Javascript
    关于DotNES
    Sql语句优化汇总(CSDN上的帖子)
  • 原文地址:https://www.cnblogs.com/andyidea/p/8409486.html
Copyright © 2011-2022 走看看