解决golang 关于全局变量的坑


Posted in Golang onMay 06, 2021

学习golang不久,在定义全局变量的时候遇见了坑。写个小例子,增强记忆。

错误版本

var p int
func main() {
 p, err := test(4)
 if err != nil {
  log.Fatal(err)
 }
}
func test(i int) (int, error) {
 return i + 1, nil
}

编译一直不通过,p declared and not used。后来查了查资料,看见这种其实是在main里边又重新定义了p,所以一直提示p定义了但是没有使用。修改如下:

正确版本

var p int
func main() {
 var err error
 p, err = test(4)
 if err != nil {
  log.Fatal(err)
 }
}
func test(i int) (int, error) {
 return i + 1, nil
}

补充: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要复杂的多的实际项目中,不经意间就可能会犯下这样的错误。

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

我的建议是这样:

尽量少的使用全局变量。

尽量少的使用:=语法糖。

使用:=的时候要确保左值没有被定义过。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
Go语言操作数据库及其常规操作的示例代码
Apr 21 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
Golang: 内建容器的用法
May 05 Golang
Goland使用Go Modules创建/管理项目的操作
May 06 Golang
浅谈Go语言多态的实现与interface使用
Jun 16 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
go goroutine 怎样进行错误处理
Jul 16 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
一文搞懂Golang 时间和日期相关函数
Dec 06 Golang
Go语言实现一个简单的并发聊天室的项目实战
Mar 18 Golang
golang语言指针操作
Apr 14 Golang
Goland使用Go Modules创建/管理项目的操作
解决goland 导入项目后import里的包报红问题
Go 自定义package包设置与导入操作
goland 设置project gopath的操作
解决Goland 同一个package中函数互相调用的问题
浅谈golang package中init方法的多处定义及运行顺序问题
golang switch语句的灵活写法介绍
May 06 #Golang
You might like
我常用的几个类
2006/10/09 PHP
PHP读取ACCESS数据到MYSQL的代码
2011/05/11 PHP
php开启安全模式后禁用的函数集合
2011/06/26 PHP
set_exception_handler函数在ThinkPHP中的用法
2014/10/31 PHP
wordpress安装过程中遇到中文乱码的处理方法
2015/04/21 PHP
PHP实现冒泡排序的简单实例
2016/05/26 PHP
PHP生成各种随机验证码的方法总结【附demo源码】
2017/06/05 PHP
PHP设计模式之模板方法模式实例浅析
2018/12/20 PHP
基于JQuery的asp.net树实现代码
2010/11/30 Javascript
javascript制作的网页侧边弹出框思路及实现代码
2014/05/21 Javascript
详谈javascript中DOM的基本属性
2015/02/26 Javascript
基于JQuery实现分隔条的功能
2016/06/17 Javascript
JavaScript函数节流概念与用法实例详解
2016/06/20 Javascript
Bootstrap按钮组简单实现代码
2017/03/06 Javascript
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
探究一道价值25k的蚂蚁金服异步串行面试题
2020/08/21 Javascript
Nuxt的动态路由和参数校验操作
2020/11/09 Javascript
python BeautifulSoup使用方法详解
2013/11/21 Python
Python编程二分法实现冒泡算法+快速排序代码示例
2018/01/15 Python
Python实现截取PDF文件中的几页代码实例
2019/03/11 Python
使用python制作一个为hex文件增加版本号的脚本实例
2019/06/12 Python
详解如何减少python内存的消耗
2019/08/09 Python
Numpy的简单用法小结
2019/08/28 Python
Python input函数使用实例解析
2019/11/22 Python
Python基础之字典常见操作经典实例详解
2020/02/26 Python
python安装和pycharm环境搭建设置方法
2020/05/27 Python
HTML5 拖放(Drag 和 Drop)详解与实例代码
2017/09/14 HTML / CSS
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
Hawes & Curtis澳大利亚官网:英国经典服饰品牌
2018/10/29 全球购物
编辑找工作求职信范文
2013/12/16 职场文书
岗位明星事迹材料
2014/05/18 职场文书
化学教育专业求职信
2014/07/08 职场文书
2015初中政治教学工作总结
2015/07/21 职场文书
学前班教学反思
2016/02/24 职场文书
Python序列化与反序列化相关知识总结
2021/06/08 Python
python3操作redis实现List列表实例
2021/08/04 Python