Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
If statement golang if初始化语句的作用域为内部if块。为什么?_If Statement_Go_Scope - Fatal编程技术网

If statement golang if初始化语句的作用域为内部if块。为什么?

If statement golang if初始化语句的作用域为内部if块。为什么?,if-statement,go,scope,If Statement,Go,Scope,我在代码中发现了一个bug func receive() (err error) { if v, err := produce(); err == nil { fmt.Println("value: ", v) } return } 这个函数永远不会返回错误,但我绝对确信它应该返回 经过一些测试,我了解到if语句中重新声明了err。更重要的是,所有变量总是在if语句中的短变量赋值中重新声明,尽管它们以前声明过 这是工作代码 func receive()

我在代码中发现了一个bug

func receive() (err error) {
    if v, err := produce(); err == nil {
        fmt.Println("value: ", v)
    }
    return
}
这个函数永远不会返回错误,但我绝对确信它应该返回

经过一些测试,我了解到if语句中重新声明了
err
。更重要的是,所有变量总是在
if
语句中的短变量赋值中重新声明,尽管它们以前声明过

这是工作代码

func receive() (err error) {
    v, err := produce()
    if err == nil {
        fmt.Println("value: ", v)
    }
    return
}
以下是一个例子:

似乎是一种假设陈述

//some code
if <init_statement>; <expression> {}
//more code
//一些代码
如果;{}
//更多代码
相当于

//some code
{
    <init_statement>
    if expression {}
}
//more code
//一些代码
{
if表达式{}
}
//更多代码
所以,我的问题是:

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

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

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

编译器可能不允许在“return”中使用空表达式列表 语句,如果使用 与结果参数相同的名称位于 返回

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

func receive1() (err error) {
    if v, err := produce(); err != nil {
        fmt.Println("value2: ", v)
        return // err is shadowed during return
    }   
    return
}
上述代码将显示一个错误,如下所示:

在返回过程中,错误被隐藏

在第二个函数中,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
}
试穿

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

func complexF3() (re float64, im float64) {
    re = 7.0
    im = 4.0
    return
}
无论它们是如何声明的,所有结果值都是 在输入到 功能。指定结果的“return”语句将设置结果 执行任何延迟函数之前的参数

1) 因为语言规范这么说

2) 它是:

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


3) 您确实在函数末尾返回了值。不要使用命名返回值。

1)因为您正在声明新的返回值2)这实际上很有趣-我也不容易找到3)您返回了一个值-这是
错误类型的默认值-
nil
似乎命名返回值根本不是个好主意(现在我删除了函数末尾的所有空return语句,并在所有位置使用显式返回。命名返回值唯一有用的情况是defer函数处理panic和returning错误