解决golang 关于全局变量的坑

 更新时间:2021年05月06日 14:54:21   作者:浪_沏沙  
这篇文章主要介绍了解决golang 关于全局变量的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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

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

我的建议是这样:

尽量少的使用全局变量。

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

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

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

相关文章

  • Go语言七篇入门教程六网络编程

    Go语言七篇入门教程六网络编程

    这篇文章主要为大家介绍了Go语言的网络编程,其中包含了Socket编程,Http编程以及RPC编程,本篇文章是Go语言七篇入门系列文章,有需要的朋友可以借鉴下
    2021-11-11
  • 一文搞懂Golang中iota的用法和原理

    一文搞懂Golang中iota的用法和原理

    我们知道iota是go语言的常量计数器,本文尝试全面总结其使用用法以及其实现原理,需要的朋友可以参考以下内容,希望对大家有所帮助
    2022-08-08
  • Go语言开发前后端不分离项目详解

    Go语言开发前后端不分离项目详解

    这篇文章主要为大家介绍了Go语言开发前后端不分离项目详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Go语言中实现完美错误处理实践分享

    Go语言中实现完美错误处理实践分享

    Go 语言是一门非常流行的编程语言,由于其高效的并发编程和出色的网络编程能力,越来越受到广大开发者的青睐。本文我们就来深入探讨一下Go 语言中的错误处理机制吧
    2023-04-04
  • Go实现set类型的示例代码

    Go实现set类型的示例代码

    本文主要介绍了Go实现set类型的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • 在Go语言中实现DDD领域驱动设计实例探究

    在Go语言中实现DDD领域驱动设计实例探究

    本文将详细探讨在Go项目中实现DDD的核心概念、实践方法和实例代码,包括定义领域模型、创建仓库、实现服务层和应用层,旨在提供一份全面的Go DDD实施指南
    2024-01-01
  • go chan基本使用详解

    go chan基本使用详解

    本文主要介绍了go chan基本使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Go语言实战之实现均衡器功能

    Go语言实战之实现均衡器功能

    这篇文章主要为大家详细介绍了如何利用Golang 实现一个简单的流浪均衡器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-04-04
  • Golang栈结构和后缀表达式实现计算器示例

    Golang栈结构和后缀表达式实现计算器示例

    这篇文章主要为大家介绍了Golang栈结构和后缀表达式实现计算器示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • golang中判断请求是http还是https获取当前访问地址

    golang中判断请求是http还是https获取当前访问地址

    这篇文章主要为大家介绍了golang中判断请求是http还是https获取当前访问地址示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10

最新评论