2

我正在阅读一本(非常好的)围棋书并看到了这个例子,但我不明白它是如何工作的。

func makeEvenGenerator() func() uint {
    i := uint(0)
    return func() (ret uint) {
        ret = i
        i += 2
        return
    }
}
func main() {
    nextEven := makeEvenGenerator()
    fmt.Println(nextEven()) // 0
    fmt.Println(nextEven()) // 2
    fmt.Println(nextEven()) // 4
}

递增i是常见的关闭行为。没关系。但是如果你看一下nextEven,它是一个不带参数并返回一个uint被调用的函数ret。但是命名返回值有什么意义呢?任何调用它的代码都不会使用自己的变量名吗?

return 语句什么也不返回 - 那么打印的是什么?0 / 2 / 4 是如何从这个函数中出来的?

这与这样做有什么不同:

func makeEvenGenerator() func() uint {
    i := uint(0)
    return func() uint {
        current := i
        i += 2
        return current
    }
}

这似乎更简单,并使事情变得更加明显。我是否缺少一些深入的围棋/数学概念?

4

1 回答 1

11

返回“无”的 return 语句正在返回命名的结果参数ret。命名结果参数 ( http://golang.org/doc/effective_go.html#named-results ) 是在函数中引入局部变量的语法糖,如果有裸返回,将返回这些变量。

在这种特定情况下,使用一个没有任何好处,而且它可能会造成混淆而不是帮助。

通常有两种使用命名结果参数的情况:当想要从 a 更改返回值时defer,以及为了记录它们的使用,通常可以在返回两个或多个值的函数中看到,例如Read(b []byte) (n int, err error)

于 2013-08-13T17:52:45.407 回答