返回输入变量在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)) 
} 

但令我惊讶的是,它没有编译抱怨重复的论点。为什么不可能返回输入参数?我做错了什么,或者只是不支持?

我认为这是一个完全有效的用例,并且它可能是这种用法的许多其他示例。

+2

函数范围内的变量名称必须是唯一的,这就是为什么 –

+0

函数的“范围”在哪里开始?在其他语言中,我的理解是,“func”和“{”是函数签名,范围介于“{”和“}”之间。可能是语言中的设计错误? –

我猜问题不是在返回输入参数,而是在名称重复:yz是在同一级别上声明两次,编译器无法区分。

我也是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:编译器不中你所期望的方式统一名称。这种隐式阴影不被支持,应该积极地避免,以防止某些容易避免的错误。