为什么可以在Go中的多个return语句中重新定义err [英] Why it is possible to redefine err in multiple return statement in Go

查看:49
本文介绍了为什么可以在Go中的多个return语句中重新定义err的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的例子来说明这个问题(它只是用来解释这个问题,但是我在实际项目中也看到了类似的代码):

Consider the following example illustrating the question (it was just built to explain the question, but I saw similar code in books as well in real projects):

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 ,但是如果我取消注释<-第1行<-第2行,它会抱怨:= 左侧没有新变量.

The compiler doesn't complain about redefining err, but if I uncomment <- line 1 or <- line 2, it will complain no new variable on left side of :=.

那么,它是如何工作的呢?为什么编译器愉快地允许在多返回语句中使用:= 而不是 n1 上的 n1 覆盖多返回语句中的 err 示例?

So, how does it work? Why the compiler happily allows to override err in multi return statement, using :=, but not n1 on <- line 2 example?

更好的是,您可以指向解释此行为的官方参考.

Better if you can point into the official reference explaining this behavior.

推荐答案

这是因为您使用了简短变量声明 := .引用规范:

It is because you used Short variable declaration :=. Quoting from the spec:

与常规变量声明不同,简短的变量声明可以重新声明,前提是它们最初是在相同类型的同一块中(如果该块是函数体,则在参数列表中)早先声明过,并且至少是非空白变量之一.因此,重新声明只能出现在多变量简短声明中.重新声明不会引入新的变量;只是为原始值分配了一个新值.

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()的返回值).

Is a multi-variable short declaration, and all variables on the left side are new, and so all will be declared (and return values of strconv.Atoi() assigned).

此行:

n2, err := strconv.Atoi("2")

这是一个多变量简短声明, n2 是新的.因此,它声明了 n2 ,并且只为 err 分配了一个新值,因为 err 已经在同一块中声明了.

It is a multi-variable short declaration, and n2 is new. So it declares n2 and only assigns a new value to err, because err is already declared in the same block.

此行:

err := fmt.Errorf("new error") <- line 1

这不是不是多变量简短声明.它会尝试声明 err ,但是已经在同一块中声明了,因此是编译时错误.

It is not a multi-variable short declaration. It would try to declare err but it is already declared in the same block, therefore it is a compile-time error.

这行:

n1, err := strconv.Atoi("3") <- line 2

这是一个多变量简短声明,但左侧的所有变量已在同一块中先前声明,因此它也是一个可编译的-时间错误(左侧没有引入任何新变量).

It is a multi-variable short declaration, but all the variables on the left side have been previously declared in the same block, so it is also a compile-time error (it doesn't introduce any new variables on the left side).

请注意,如果先前已经声明了左侧的所有变量,只需将其从短变量声明:= 更改为

Note that if all the variables on the left side have been previously declared, simply changing from Short variable declaration := to Assignment = will make it work (assumed values on the right side are assignable to the variables on the left side).

这篇关于为什么可以在Go中的多个return语句中重新定义err的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆