for循环中的短格式var声明



请看下面的代码。(A)在围棋中不行,我理解为什么。但是为什么(B)在Go中可以呢?

(A)不可以:因为重新定义了a(LHS中没有新的变量:=)

(B)也应该是一个错误:因为重新定义r(在LHS of:=中没有新的变量),因为循环将在每次迭代时执行r :=,而r仍在作用域中。

package main
import "fmt"
func main() {
a := make([]byte, 10)
fmt.Println(a)
a := make([]byte, 10) //not ok and I understand why : (A)
fmt.Println(a)
for i := 0; i < 5; i++ {
r := make([]byte, 10) //ok, but why is this ok? : (B)
fmt.Println(r)
}
}

短格式声明背后的关键思想是,它必须在当前块中定义至少一个新变量。所以它在第一种情况下失败了,因为它试图在不引入任何新变量的情况下重新定义当前块中的a。第二个块可以工作,因为r是在当前块中声明的新变量。

正如go文档规范中关于Short_variable_declarations的描述,它对于作用域是临时的。

与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初是在相同类型的同一块(或参数列表,如果块是函数体)中声明的,并且至少有一个非空白变量是新的。因此,重声明只能出现在多变量短声明中。重声明不引入新变量;它只是给原来的赋一个新值。

短变量声明只能出现在函数内部。在某些上下文中,例如"&;if&;"、"&;for&;"或"&;switch&;"的初始化式语句,它们可用于声明局部临时变量。

不能在同一作用域中用短变量声明重新声明相同的变量。

a, a := 1, 2                              // illegal: double declaration of a or no new variable if a was declared elsewhere

在您的示例中,r处于循环作用域中,并且每次迭代r都是一个新变量。因为for循环会重复执行一个块。

"for"语句指定重复执行一个块

如果您需要澄清这一点,请运行下面的循环代码,并查看r的每次迭代的内存地址。它将打印五个不同的地址。

for i := 0; i < 5; i++ {
r := make([]byte, 10) //ok, but why is this ok? : (B)
fmt.Printf("%pn",r)
}

最新更新