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

Sud*_*han 2 closures go

我正在读一本(非常好的)Go书并看到了这个例子,但我看不出它是如何工作的.

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
}
Run Code Online (Sandbox Code Playgroud)

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

并且return语句什么都不返回 - 所以什么被打印?0/2/4如何从这个功能出来?

这与此有何不同:

func makeEvenGenerator() func() uint {
    i := uint(0)
    return func() uint {
        current := i
        i += 2
        return current
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Dom*_*nef 11

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

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

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