以下代码预计会在编译时失败并出现错误:
package main
import (
"fmt"
)
func main() {
x := 10
x := x + 1
fmt.Println(x)
}
编译错误是:./prog.go:9:4: no new variables on left side of :=
所以我期待这段代码也会因错误而失败:package main
import (
"fmt"
)
func main() {
if x := 10; x < 10 {
fmt.Println("if block: x:", x)
} else if x := x + 1; x < 20 {
fmt.Println("else if block: x: ", x)
}
}
这是输出:else if block: x: 11
为什么即使 :=
中的 else if x := x + 1
运算符没有定义任何新变量,第二个程序也会成功?
最佳答案
根据 Go 规范,以下是 if
语句的定义方式:IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
后来,在 Declarations and Scope 部分中说:
An identifier declared in a block may be redeclared in an inner block. While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration.
所以现在,
if
语句是一个 implicit block :Each "if", "for", and "switch" statement is considered to be in its own implicit block.
那么从
IfStmt
的定义中可以看出,在关键字else
之后可能又会出现一个IfStmt
,它是中的一个隐式块,另一个IfStmt
(仍然是一个隐式块),满足重新声明标识符的条件。也与显式块进行比较:
func foo() {
x := 10
{
x := 20
fmt.Println("Inner x:", x) // 20
}
fmt.Println("Outer x:", x) // 10
}
关于go - 为什么 `else if x := x + 1` 即使没有在 := 左侧定义新变量也不会编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63272034/