为了清楚起见,我将为这两个函数分配名称:
func makeEvenGenerator() func() uint { // call this "the factory" i := uint(0) return func() (ret uint) { // call this "the closure" ret = i i += 2 return }}工厂返回闭包–函数是Go中的一等公民,即它们可以是右手表达式,例如:
f := func() { fmt.Println("f was called"); }f() // prints "f was called"在您的代码中,闭包环绕工厂的上下文,这称为 词法作用域 。这就是变量
i在闭包内部可用的原因,而不是作为副本而是作为对
i自身的引用。
封闭使用 命名返回值 叫
ret。这意味着在闭包内部您将隐式声明
ret,在时
return,
ret将返回任何值。
这行:
ret = i
会将的当前值分配
i给
ref。它不会改变
i。但是,这一行:
i += 2
将
i在下次调用闭包时更改的值。
在这里,您会找到我为您写的一个封闭示例。我认为它不是非常有用,但可以很好地说明闭包的范围,目的和用法:
package mainimport "fmt"func makeIterator(s []string) func() func() string { i := 0 return func() func() string { if i == len(s) { return nil } j := i i++ return func() string { return s[j] } }}func main() { i := makeIterator([]string{"hello", "world", "this", "is", "dog"}) for c := i(); c != nil; c = i() { fmt.Println(c()) }}


