函数的闭包

程序员成长之旅 · 程序员成长之旅/Go语言学习/笔记 · 526 字

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 }