函数的闭包
Go 函数可以是一个闭包。闭包是一个函数值, 它引用了其函数体之外的变量 。 该函数可以访问并赋予其引用的变量的值 ,换句话说,该函数被这些变量“绑定”在一起。
虽然不能在一个函数里直接声明另一个函数,但是可以在一个函数中声明一个匿名函数类型的变量,此时的匿名函数称为闭包(closure)
例如,函数 adder 返回一个闭包。每个闭包都被绑定在其各自的 sum 变量上。
package main import "fmt" func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum } } func main() { pos, neg := adder(), adder() for i := 0; i < 10; i++ { fmt.Println( pos(i),//sum 逃逸了,它的生命周期没有随着它的作用域结束而结束。 neg(-2i), ) } } //看上去有点乱 优化一下... package main import "fmt" func adder() ( func(int) int ) {//把返回类型包了起来 sum := 0 return func(x int) (int) {//把返回类型包了起来,因为一直有函数在引用sum 随意垃圾回收并不会将sum回收,所以我们就一直可以对sum操作~ sum += x return sum } } func main() { pos, neg := adder(), adder() for i := 0; i < 10; i++ { fmt.Println( pos(i), neg(-2i), ) } }
x
1 package
main 2 3 import
"fmt" 4 5 func
adder () func ( int ) int { 6
sum :
0 7
return
func ( x
int ) int { 8
sum
+=
x 9
return
sum 10
} 11 } 12 13 func
main () { 14
pos , neg :
adder (), adder () 15
for
i :
0 ; i
<
10 ; i ++ { 16
fmt . Println ( 17
pos ( i ), //sum 逃逸了,它的生命周期没有随着它的作用域结束而结束。 18
neg (
2 * i ), 19
) 20
} 21 } 22 //看上去有点乱 优化一下... 23 package
main 24 25 import
"fmt" 26 27 func
adder () ( func ( int ) int ) { //把返回类型包了起来 28
sum :
0 29
return
func ( x
int ) ( int ) { //把返回类型包了起来,因为一直有函数在引用sum 随意垃圾回收并不会将sum回收,所以我们就一直可以对sum操作~ 30
sum
+=
x 31
return
sum 32
} 33 } 34 35 func
main () { 36
pos , neg :
adder (), adder () 37
for
i :
0 ; i
<
10 ; i ++ { 38
fmt . Println ( 39
pos ( i ), 40
neg (
2 * i ), 41
) 42
} 43 }