【问题标题】:How does this example of a Go closure work?这个 Go 闭包的例子是如何工作的?
【发布时间】:2013-08-13 17:47:28
【问题描述】:

我正在阅读(非常好)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,它是一个不带参数并返回一个称为retuint 的函数。但是命名返回值有什么意义呢?调用它的代码不会使用自己的变量名吗?

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

这与这样做有什么不同:

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

这看起来更简单,也让事情变得更明显。我是否缺少一些深入的围棋/数学概念?

【问题讨论】:

标签: go closures


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-02
    • 2021-07-24
    • 2021-10-05
    • 2017-11-26
    • 2021-10-14
    • 2021-10-05
    • 1970-01-01
    • 2014-10-22
    相关资源
    最近更新 更多