Golang变量a为何被遮蔽?如何避免冗余赋值操作?
Golang变量遮蔽问题的最优解法
你的问题核心是内部代码块使用:=时,同时声明了新的a和err,导致外部作用域的a被遮蔽,内部修改的是局部变量而非外部的a。不用新增中间变量的最优解法有两种:
方案一:提前在外部作用域声明err变量
在外部作用域提前声明err,这样内部块可以使用普通赋值=而非:=,不会创建新的局部a:
package main import ( "fmt" ) func work() { a := "outside" var err error // 提前声明err,避免内部触发变量声明 { a, err = foo() // 直接赋值给已存在的a和err fmt.Printf("here: %v %v\n", a, err) } fmt.Printf("but here: %v \n", a) } func foo() (string, error) { return "inside", fmt.Errorf("WTF?") } func main() { work() }
运行后外部的a会被正确更新为inside,因为这里没有创建新的局部a,只是修改了外部作用域的变量。
方案二:在内部块单独声明err后赋值
如果不想在外部作用域保留err变量,可以将err的声明限制在内部块中,再用赋值语句更新a:
package main import ( "fmt" ) func work() { a := "outside" { var err error a, err = foo() // 赋值给外部的a和内部的err fmt.Printf("here: %v %v\n", a, err) } fmt.Printf("but here: %v \n", a) } func foo() (string, error) { return "inside", fmt.Errorf("WTF?") } func main() { work() }
这种方式既解决了变量遮蔽问题,又把err的作用域限定在内部块,避免污染外部作用域。
原理说明
:=是Go的短变量声明运算符,只要左边有一个未声明的变量,就会在当前作用域创建所有左边的变量。你原来的代码中,err未声明,所以a, err := foo()会在内部块创建新的局部a,遮蔽外部的a。而使用=赋值时,要求左边所有变量都已存在,因此只会修改已有的变量,不会创建新变量。
内容的提问来源于stack exchange,提问作者YotKay
相关产品推荐
相关产品推荐

