为什么可以在 Go 中的 multiple return 语句中重新定义 err
Why it is possible to redefine err in multiple return statement in Go
考虑以下示例说明问题(它只是为了解释问题而构建的,但我在书本和实际项目中看到了类似的代码):
package main
import (
"strconv"
"fmt"
"log"
)
func main() {
n1, err := strconv.Atoi("1")
if err != nil {
log.Panicf("%v", err)
}
n2, err := strconv.Atoi("2")
if err != nil {
log.Panicf("%v", err)
}
// err := fmt.Errorf("new error") <- line 1
// n1, err := strconv.Atoi("3") <- line 2
fmt.Printf("n1 = %d, n2 = %d\n", n1, n2)
}
编译器不会抱怨重新定义 err
,但如果我取消注释 <- line 1
或 <- line 2
,它会抱怨 no new variable on left side of :=
.
那么,它是如何工作的?为什么编译器很高兴地允许在多 return 语句中覆盖 err
,使用 :=
,而不是 <- line 2
示例中的 n1
?
如果您能指向解释此行为的官方参考资料就更好了。
因为你使用了Short variable declaration:=
。引用规范:
Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.
这一行:
n1, err := strconv.Atoi("1")
是一个多变量短声明,左边的所有变量都是新的,所以都会被声明(并且strconv.Atoi()
赋值return)。
这一行:
n2, err := strconv.Atoi("2")
是多变量短声明,n2
是新的。所以它声明了n2
并且只给err
赋了一个新值,因为err
已经在同一个块中声明了
这一行:
err := fmt.Errorf("new error") <- line 1
不是多变量短声明。它会尝试声明 err
但它已经在同一个块中声明,因此这是一个编译时错误。
还有这一行:
n1, err := strconv.Atoi("3") <- line 2
这是一个多变量短声明,但是左边的所有变量已经之前在同一个块中声明 ,所以也是编译时错误(左边没有引入任何新的变量)。
注意如果左边的所有变量之前都声明过,只需将Short variable declaration :=
改为Assignment =
will make it work (assumed values on the right side are assignable左边的变量即可)。
考虑以下示例说明问题(它只是为了解释问题而构建的,但我在书本和实际项目中看到了类似的代码):
package main
import (
"strconv"
"fmt"
"log"
)
func main() {
n1, err := strconv.Atoi("1")
if err != nil {
log.Panicf("%v", err)
}
n2, err := strconv.Atoi("2")
if err != nil {
log.Panicf("%v", err)
}
// err := fmt.Errorf("new error") <- line 1
// n1, err := strconv.Atoi("3") <- line 2
fmt.Printf("n1 = %d, n2 = %d\n", n1, n2)
}
编译器不会抱怨重新定义 err
,但如果我取消注释 <- line 1
或 <- line 2
,它会抱怨 no new variable on left side of :=
.
那么,它是如何工作的?为什么编译器很高兴地允许在多 return 语句中覆盖 err
,使用 :=
,而不是 <- line 2
示例中的 n1
?
如果您能指向解释此行为的官方参考资料就更好了。
因为你使用了Short variable declaration:=
。引用规范:
Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.
这一行:
n1, err := strconv.Atoi("1")
是一个多变量短声明,左边的所有变量都是新的,所以都会被声明(并且strconv.Atoi()
赋值return)。
这一行:
n2, err := strconv.Atoi("2")
是多变量短声明,n2
是新的。所以它声明了n2
并且只给err
赋了一个新值,因为err
已经在同一个块中声明了
这一行:
err := fmt.Errorf("new error") <- line 1
不是多变量短声明。它会尝试声明 err
但它已经在同一个块中声明,因此这是一个编译时错误。
还有这一行:
n1, err := strconv.Atoi("3") <- line 2
这是一个多变量短声明,但是左边的所有变量已经之前在同一个块中声明 ,所以也是编译时错误(左边没有引入任何新的变量)。
注意如果左边的所有变量之前都声明过,只需将Short variable declaration :=
改为Assignment =
will make it work (assumed values on the right side are assignable左边的变量即可)。