我刚开始使用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))
}
但令我惊讶的是,它没有编译抱怨重复的论点。为什么不能返回输入参数?我做错了什么还是不支持?
我认为这是一个完全有效的用例,并且可能有许多其他示例用于此用途。
答案 0 :(得分:4)
我也是Golang的初学者。这是我设法找到的。
问题基本上是,您声明了两个名为z
的变量,然后期望它们是统一的。这是不受支持的,实际上会违反命名返回类型的主要目标,即记录返回值的含义。
为了更详细地解释,这有点像编写以下代码:
func badFunction(a int) int {
var a int = 0
return a
}
变量被声明两次,这对Go来说很困惑。如果我们看一下'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
,这是一个相关的,虽然不可否认的错误。您在那里收到的错误消息似乎基本上是一个预先检查,以防止用户看到desugared时生成的代码。
作为this Stackoverflow question报告,命名返回值应基本上仅用于文档。但是,它确实提到了意外阴影的可能性。可能是早期的Go版本支持这个,但后来已经改变以防止由于这种名称冲突导致的错误,但是我没有发现任何与此相关的内容。
关于该主题的effective go section也有话要说:
返回或结果"参数" Go函数的名称可以给出名称并用作常规变量,就像传入的参数一样。命名时,在函数开始时将它们的类型初始化为零值; 如果函数执行不带参数的return语句,则结果参数的当前值将用作返回值。
名称不是强制性的,但可以使代码更短更清晰:他们的文档。
TL; DR:编译器不会以您期望的方式统一名称。这种隐式阴影不受支持,应该主动避免,以防止某些容易避免的错误。
答案 1 :(得分:3)
我猜问题不在于返回输入参数,而是在名称重复中:y
和z
在同一级别上声明两次,编译器无法区分。
答案 2 :(得分:0)
当您以返回类型声明变量时,Go编译器会认为您正在声明该变量以备将来使用。
现在,当编译器在输入和返回部分看到相同的变量名称时,它将报告重复的参数问题。
如果愿意,您可以尝试以下工作示例
func swap(x, y string) (a string, b string) {
a = y
b = x
return
}
答案 3 :(得分:0)
您可以这样做
CallNextHookEx
或者如果您真的想使用变量,可以这样
func checkError(err *error) (bool, *error) {
if err != nil {
return false, err
} else {
return false, nil
}
}