Golang变量遮蔽——Shadowing

2023-10-29 17:30
文章标签 golang 变量 遮蔽 shadowing

本文主要是介绍Golang变量遮蔽——Shadowing,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在golang中,我们经常会用:=来声明变量,这很方便但也会带来一些问题。当变量遇到作用域时就容易产生shadowing。

 

比如说我们经常会遇到的:

shadow: declaration of "err" shadows declaration

 

什么是变量隐藏呢?

 

就是当年在后面重新声明了前面已经声明的同名变量时,后面的变量值会遮蔽前面的变量值,虽然这两个变量同名但值却不一样。这样是很容易产生问题的。

 

举个栗子来看一下:

func main() {n := 0if true {n := 1n++}fmt.Println(n) // 0}这个结果n=0

 

这里因为在if的作用域中对n重新声明了,所以里面的n++对外面的n并不起作用。

 

如果是在里面对n直接赋值而不是重新声明呢?

func main() {n := 0if true {n = 1n++}fmt.Println(n) // 2}这里结果n=2

 

 

这么明显的情况我们写代码的时候很容易发现,但如果是很复杂的代码呢,尤其是遇到err的时候真的很容易Shadowing。

 

再举个栗子:

func templateToFile(templateFilename string, filename string, data interface{}) (err error) {if f, err := os.OpenFile(filename, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err == nil {defer f.Close()if t, err := template.ParseFiles(templateFilename); err == nil {return t.Execute(f, data)}}return}

 

这里第一个if作用域中的err和第二个作用域中的err不是同一个东西,但又是相同名的变量,所以也会造成变量遮蔽。

如何解决呢,这种一般把第二个err变量改名或者用赋值代理重新声明就可以解决了。

 

那对于这种变量遮蔽的情况,如何检测呢?

 

情况严重的话你的代码会直接编译失败,但如果不严重的情况你的代码是跑的起来的,但仍然会存在遮蔽的情况。

 

1,可以用vet,Go 1.12 以上的版本需要

go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadowgo vet -vettool=$(which shadow)

 

2,也可以用goland的tool工具(我一般用这种)

 

3,还可以用golangci-lint工具,也可以检测出来。

 

 

 

这篇关于Golang变量遮蔽——Shadowing的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/302209

相关文章

一文全面详解Python变量作用域

《一文全面详解Python变量作用域》变量作用域是Python中非常重要的概念,它决定了在哪里可以访问变量,下面我将用通俗易懂的方式,结合代码示例和图表,带你全面了解Python变量作用域,需要的朋友... 目录一、什么是变量作用域?二、python的四种作用域作用域查找顺序图示三、各作用域详解1. 局部作

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.

golang中slice扩容的具体实现

《golang中slice扩容的具体实现》Go语言中的切片扩容机制是Go运行时的一个关键部分,它确保切片在动态增加元素时能够高效地管理内存,本文主要介绍了golang中slice扩容的具体实现,感兴趣... 目录1. 切片扩容的触发append 函数的实现2. runtime.growslice 函数gro

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

Golang interface{}的具体使用

《Golanginterface{}的具体使用》interface{}是Go中可以表示任意类型的空接口,本文主要介绍了Golanginterface{}的具体使用,具有一定的参考价值,感兴趣的可以了... 目录一、什么是 interface{}?定义形China编程式:二、interface{} 有什么特别的?✅

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据