这个Go闭包的例子如何运作?

时间:2013-08-13 17:47:28

标签: go closures

我正在阅读(非常好)Go book并看到了这个例子,但我看不出它是如何运作的。

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的{​​{1}}。但是命名返回值的重点是什么?调用它的任何代码都不会使用自己的变量名吗?

并且return语句什么也没有返回 - 所以正在打印什么? 0/2/4是如何从这个功能出来的?

这与这样做有什么不同:

ret

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

1 个答案:

答案 0 :(得分:11)

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

在这个特定的情况下,使用一个没有任何好处,它可能会比它有助于混淆。

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