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