golang短变量命名空间问题

it2024-07-07  38

场景一

package main func main() { a := 1 println(&a) a, b := 2, true println(b) println(&a) } /** 结果 0xc000085f48 true 0xc000085f48 */

分析:由于在相同的命名空间下,a, b := 1, true中的变量a并没有覆盖掉之前定义的a变量,仅仅是创建了变量b。如果将b换成_,上面的代码会报:=没有新变量产生的错误,也可佐证。

场景二

package main func main() { a := 1 if a, b := 2, true; b { println(&a) } println(&a) } /** 结果 0xc00008bf40 0xc00008bf48 */

分析:因为if是一个新的命名空间,因此if语句中的变量a覆盖的外层命名空间的a变量。此外,if语句内部也是独立的命令空间。

场景三

package main var a = 1 func main() { println(&a) a, _ := 2, true println(&a) } /** 结果 0x80f230 0xc000085f48 */

分析:全局变量和函数也是两个命名空间,main函数中的变量a覆盖了全局变量a。注意到此时的代码没有报错,也说明了main函数中的a是一个新的变量。 另外,此次两个a变量的地址差别也很大。这是因为全局变量在程序的数据段,而局部变量在栈中分配。

总结

说了这么多有什么用呢? 其实与go语言对error的处理方式有关,if的新语法,短变量定义,多返回值都有部分原因是为了处理error更方便。

package main func main() { a, err := testA() if err != nil { //handle error } if b, err := testB(); err == nil { //handle success } }

短变量声明可以减少变量声明的代码,但是使用的时候也要注意被赋值的变量是不是你想要的那个变量。特别是变量在别处已经声明过的情况,可能你在定义一个新变量,而不是给变量赋值。

对于以上三个场景,总结起来就是对于:=如果变量在同命名空间下已声明过,则不会产生新变量;否则都会产生新变量。

最新回复(0)