【问题标题】:golang if initialization statement scoped to inner if block. Why? [duplicate]golang if 初始化语句的范围为内部 if 块。为什么? [复制]
【发布时间】:2018-08-28 09:44:27
【问题描述】:

我在我的代码中发现了一个错误

func receive() (err error) {
    if v, err := produce(); err == nil {
        fmt.Println("value: ", v)
    }
    return
}

这个函数永远不会返回错误,但我绝对确定它应该返回。

经过一些测试,我了解到err 在 if 语句中被重新声明。不仅如此 - 所有变量总是在 if 语句中的短变量赋值中重新声明,尽管它们之前已声明过。

这是工作代码

func receive() (err error) {
    v, err := produce()
    if err == nil {
        fmt.Println("value: ", v)
    }
    return
}

这里是一个例子:https://play.golang.org/p/1AWBsPbLiI1

好像是if语句

//some code
if <init_statement>; <expression> {}
//more code

等价于

//some code
{
    <init_statement>
    if expression {}
}
//more code

所以,我的问题:

1) 为什么不使用现有变量

2) 为什么文档/语言规范中未提及此类范围

3) 为什么编译器不说没有人返回值

【问题讨论】:

  • 1) 因为您要声明新的 2) 这实际上很有趣 - 我也不容易找到 3) 您返回一个值 - 这是 error 类型的默认值 - @ 987654329@

标签: if-statement go scope


【解决方案1】:

1) 因为语言规范是这样说的。

2) 它是:

每个“if”、“for”和“switch”语句都被认为是在它自己的隐式块中”

3) 您确实在函数结束时返回。不要使用命名的返回值。

【讨论】:

  • 似乎命名返回值根本不是个好主意(现在我删除了函数末尾的所有空返回语句并在所有地方使用显式返回。命名返回值有用的唯一情况是 -处理恐慌和返回错误的延迟函数
【解决方案2】:

编译器可能不允许在“返回”中使用空表达式列表 如果一个不同的实体(常量、类型或变量)与 与结果参数相同的名称在范围内 返回。

尝试在 if 范围内返回值,您将知道 err 变量在 if 范围内被隐藏。

func receive1() (err error) {
    if v, err := produce(); err != nil {
        fmt.Println("value2: ", v)
        return // err is shadowed during return
    }   
    return
}

上面的代码会显示错误:

错误在返回过程中被隐藏

Playground example

而在第二个函数中,return 语句中声明的 err 被分配了局部变量范围:

// err is the return value. It's OK
func receive2() (err error) {
    v, err := produce()
    if err != nil {
        fmt.Println("value2: ", v)
        return
    }
    return
}

试试playground

如果函数的结果类型为其结果参数指定名称,则表达式列表可能为空。结果参数充当普通的局部变量,函数可以根据需要为它们赋值。 “return”语句返回这些变量的值。

func complexF3() (re float64, im float64) {
    re = 7.0
    im = 4.0
    return
}

不管它们是如何声明的,所有的结果值都是 在进入 功能。指定结果的“return”语句设置结果 执行任何延迟函数之前的参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2019-05-30
    • 2015-05-06
    相关资源
    最近更新 更多