Go 闭包

在 Go 中可以在一个函数里创建另一个函数。如下:

func main() {
	add := func(x, y int) int {
		return x + y
	}

	fmt.Println(add(1,1))
}

add 是一个属性为 func(int, int) int (两个 int 类型参数,返回值类型为 int 的函数)的局部变量。这样的局部函数还可以访问其他局部变量。

func main() {
	x := 0
	increment := func() int {
		x++
		return x
	}

	fmt.Println(increment())
	fmt.Println(increment())
}

increment 函数为在 main 函数作用域中定义的变量 x 加1。 变量 x 可以被 increment 函数访问和修改。所以以上程序第一行将会输出:1,第二行将会输出:2。

这样的函数以及它引用的非本地变量称为闭包。 在本示例中,increment 函数和变量 x 形成闭包。

使用闭包的一种方法是编写一个函数,该函数返回另一个函数 - 当被调用时 - 可以生成一个数字序列。 例如,我们可以生成所有的偶数:

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
}

makeEvenGenerator 返回一个生成偶数的函数。 每次调用它时,它会将2添加到本地i变量中 - 与正常的局部变量不同,它会在调用之间保持不变。

原文

Closure