在golang中返回输入变量

时间:2017-10-08 20:12:20

标签: go return

我刚开始使用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))
}

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

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

4 个答案:

答案 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)

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

答案 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
    }
}
相关问题