golang变量作用域问题-避免使用全局变量
2018-02-03 14:55
351 查看
最近遇到了一个变量作用域的问题,一个比较低级的问题,可能作为一个熟手不应该犯这样的低级错误,但是golang的语法特点可能让你稍微不注意就踩坑,嘿嘿。
输出:
执行之后,在init和main中打印出了不一样的数字,为什么会不一样呢,可能你仔细一看就知道原因了。很简单,init中的t是用
我本想在init中给全局变量t赋值的,却不小心用
输出:
没有使用
这个问题很难保证说下次一定不会出现的,除非你彻底不用全局变量或者彻底不用
尽量少的使用全局变量。
尽量少的使用
使用
变量作用域
全局变量的作用域是整个包,局部变量的作用域是该变量所在的花括号内,这是一个很基础的问题。我们通常会使用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要复杂的多的实际项目中,不经意间就可能会犯下这样的错误。这个问题很难保证说下次一定不会出现的,除非你彻底不用全局变量或者彻底不用
:=这样的语法糖。我的建议是这样:
尽量少的使用全局变量。
尽量少的使用
:=语法糖。
使用
:=的时候要确保左值没有被定义过。
相关文章推荐
- 《编写可维护的JavaScript》读书笔记第6章:避免使用全局变量
- VC 在DLL中使用全局变量出现异常问题
- Android使用static定义全局变量被系统回收的问题
- 使用shell全局变量出现的问题
- Android 使用全局变量的问题
- 《编写可维护的JavaScript》读书笔记第6章:避免使用全局变量
- jquery 异步事件 (使用异步事件 改变页面全局变量问题)
- js使用心得——避免全局变量冲突的小技巧
- .net 全局变量 静态变量使用问题
- 关于静态库中使用全局变量可能导致的问题
- <<编写可维护的JavaScript>>之避免使用全局变量
- 尽量避免使用全局变量,以防与其它函数重名影响运行结果
- 关于静态库中使用全局变量可能导致的问题
- 解决多重定义问题/如何声明全局变量让多个cpp文件使用
- j2ee高并发时使用全局变量需要注意的问题
- 今天又哥哥问俺php 全局变量的使用问题了,俺在这里发个简单的例子
- 避免使用全局变量
- 避免使用全局变量
- MFC 全局变量与宏定义的使用问题
- c语言全局变量使用问题