返回输入变量在golang
我刚刚开始Golang,我看到了典型的交换功能例如:返回输入变量在golang
func swap(x, y string) (string, string) {
return y, x
}
我自动认为命名的回报可能已经解决了它,这是一个甜蜜的例子,所以我尝试了较短的版本:
package main
import "fmt"
func swap(z, y int) (z, y int) {
return
}
func main() {
fmt.Println(swap(2, 3))
}
但令我惊讶的是,它没有编译抱怨重复的论点。为什么不可能返回输入参数?我做错了什么,或者只是不支持?
我认为这是一个完全有效的用例,并且它可能是这种用法的许多其他示例。
我猜问题不是在返回输入参数,而是在名称重复:y
和z
是在同一级别上声明两次,编译器无法区分。
我也是Golang初学者。这是我设法找出来的。
问题实质上是,你声明了两个名为z
的变量,然后期望它们是统一的。这不被支持,实际上会违背命名返回类型的主要目标,这是为了记录返回值的含义。
为了更详细地解释,这是一个有点像写下面的代码:
func badFunction(a int) int {
var a int = 0
return a
}
声明一个变量两次,这是混淆了围棋。如果我们看看'tour of go'关于命名返回值的说法,我们可以看到这个问题。这不是最大的来源,但它仍然是一个来源:
Go的返回值可能会被命名。如果是这样,它们被视为在函数顶部定义的变量。
也就是说,你的例子是几乎完全一样badFunction
。编译器,它看起来有点像这样:
func swap(a, b int) (int, int) {
var a int = 0
var b int = 0
return b, a
}
当然,编译器抱怨a redeclared in block
,这是一个相关但无可否认不等于错误。您收到的错误消息似乎基本上是一个预先检查,以防止用户看到脱机时生成的代码。
由于this * question报告,命名返回值主要应只文档。但是,它确实提到了意外隐藏的可能性。这可能是早期的Go版本支持这一点,但后来为了防止由于这种名称冲突引起的错误而进行了更改,但是我没有发现任何与此相关的内容。
关于这个专题的effective go section也有话要说:
返回或导致一个围棋功能的“参数”可以给名称和用作常规变量,就像传入的参数。在命名时,它们在函数开始时被初始化为它们类型的零值;如果函数执行不带参数的返回语句,则将结果参数的当前值用作返回值。
这些名称并不是强制性的,但它们可以使代码变得更简短更清晰:它们是文档。
TL; DR:编译器不中你所期望的方式统一名称。这种隐式阴影不被支持,应该积极地避免,以防止某些容易避免的错误。
函数范围内的变量名称必须是唯一的,这就是为什么 –
函数的“范围”在哪里开始?在其他语言中,我的理解是,“func”和“{”是函数签名,范围介于“{”和“}”之间。可能是语言中的设计错误? –