首页 > 其他分享 >关于全局变量的坑, golang熟手们经常遇到

关于全局变量的坑, golang熟手们经常遇到

时间:2024-05-27 10:00:25浏览次数:14  
标签:main err golang init 熟手 Go 全局变量

关于全局变量的坑, golang熟手们经常遇到

原创 fengzi Go语言圈 2024-05-27 08:30 广东 听全文 Go语言圈 Go语言开发者的学习好助手,分享Go语言知识,技术技巧,学习与交流Go语言开发经验,互动才有助于技术的提升,每天5分钟,助你GO语言技术快乐成长 160篇原创内容 公众号

 

学习与交流:Go语言技术微信群

商务合作加微信:LetsFeng

 

现在就开始你的Go语言学习之旅吧!人生苦短,let’s Go.

 

 



学习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的语法特点可能让你稍微不注意就踩坑,嘿嘿。

》》》程序员福利《《《

2024年全网最新JetBrains系列IDE全家桶激活码

点击获取:https://web.52shizhan.cn

 

变量作用域
全局变量的作用域是整个包,局部变量的作用域是该变量所在的花括号内,这是一个很基础的问题。

我们通常会使用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

执行之后,在initmain中打印出了不一样的数字,为什么会不一样呢,可能你仔细一看就知道原因了。很简单,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要复杂的多的实际项目中,不经意间就可能会犯下这样的错误。

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

我的建议是这样:

  • 尽量少的使用全局变量。

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

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

 

 

 

文章链接:https://www.jb51.net/article/211453.htm

更多相关Go语言的技术文章或视频教程,请关注本公众号获取并查看,感谢你的支持与信任!

学Go语言哪些事儿290 学Go语言哪些事儿 · 目录 上一篇2024 年 05 月编程语言排行榜,Go会挤掉C#的排名吗? 阅读 434 ​ 喜欢此内容的人还喜欢   Golang 中 JSON 操作的 5 个常见陷阱(建议收藏!)     Go Official Blog   不看的原因   Golang:使用wellington/go-libsass对CSS进行预处理     我看过的号 Coding Big Tree   不看的原因   深入理解Gin中间件:Go语言框架的强大功能     我关注的号 Go大神   不看的原因   写留言       Go语言圈            

人划线

 

标签:main,err,golang,init,熟手,Go,全局变量
From: https://www.cnblogs.com/cheyunhua/p/18214932

相关文章

  • 使用Golang调用腾讯云邮件模版发送邮件
    文章目录一、腾讯云邮件模版创建1.1发信域名配置1.2发信地址设置1.3发信模版设置二、通过Golang发送邮件2.1代码示例2.2代码说明三、常见问题3.1UnsupportedRegion3.2InvalidTemplateID本文档介绍了如何使用Golang编写代码,通过腾讯云邮件服务(SES)发送带有模......
  • 使用树梅派搭建Golang、Python、NodeJs的开发服务器
    使用树梅派搭建Golang、Python、NodeJs的开发服务器安装系统安装rpi-imagersudoaptinstallrpi-imager打开rpi-imager烧写RaspberryPiOSLite(64-bit)系统设置好用户名、密码、wifi、ssh等信息上电修改镜像源备份/etc/apt/sources.listsudocp/etc/apt......
  • Golang 序列化与反序列化,包含字段首字母小写和字段时间格式化
     golang结构体json的时间 序列化与反序列化 格式化解决方案 //最近开发项目时候发现一个结构体的Json转换的时间格式问题。//即这种1993-01-01T20:08:23.000000028+08:00这种表示UTC方法。//从我们习惯来说,更喜欢希望的是1993-01-0120:08:23这种格式如......
  • linux 用脚本定义全局变量
    新建一个脚本比如gvar.sh然后可以在里面添加全局变量exportCC_PREFIX=/opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.2exportPATH=$CC_PREFIX/bin:$PATHexportLD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATHexportLD_LIBRARY_PATH=$CC_PREFIX/loo......
  • 【启程Golang之旅】基本变量与类型讲解
    欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了解这门语言的基础知识和实用技巧。目录变量的概念数据类型的概念数据类型转换基本......
  • Golang:使用go-resty/resty发送http请求get和post
    Golang:使用go-resty/resty发送http请求get和post原创 吃个大西瓜 CodingBigTree 2024-05-2508:00 北京 听全文 go-resty/resty是一个简单的HTTP和REST客户端,受到Rubyrest-client的启发文档https://github.com/go-resty/resty/安装go get github......
  • Golang初学:项目目录结构,project-layout 项目
    goversiongo1.22.1windows/amd64Windows11+amd64x86_64x86_64GNU/Linux--- 序章golang项目的代码要怎么组织?怎么放比较简洁易读?看下面这个项目就晓得了。 project-layouthttps://github.com/golang-standards/project-layout注,有时访问失败。特写文记录。......
  • Golang 实现Java的AES ECB 加密
    JavapublicstaticStringencryptAesEcb(Stringtarget,StringsKey)throwsException{byte[]raw=sKey.getBytes("UTF-8");//"AES"就是用AES/ECB/PKCS5PaddingSecretKeySpecskeySpec=newSecretKeySpec(raw,......
  • 【Golang】在Go语言中如何实现接口
    文章目录前言一、函数解释二、代码实现三、总结前言接口是Go语言中的一个核心概念,它为类型定义了行为。接口提供了一种方式,使得不同的类型可以被同样对待,只要它们实现了相同的接口。在这篇博客中,我们将讨论如何在Go语言中实现接口。一、函数解释在Go语言中,接口是......
  • golang 的学习曲线
     Go(Golang)语言的设计目标之一就是让其学习曲线尽可能平缓,这意味着对于大多数开发者来说,学习Go语言比许多其他现代编程语言可能更快上手。以下是通常Golang学习曲线的一个概述:1入门阶段: 基本语法:Go语言的语法相对简单,与C/C++和Java有一定的相似性,所以对于有这些背景的开发......