Go语言闭包
Posted gyyyl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言闭包相关的知识,希望对你有一定的参考价值。
总的来说,闭包就是一个函数,他的返回值也是一个函数,并且作为返回值的这个函数能够调用之前函数的参数:
// 函数作为返回值和作为返回值的这个函数能够调用之前函数的参数,就是Go语言闭包的精髓 // 可以类比为python中的装饰器 func f1(x int) func() { return func() { // 返回值就是这个匿名函数 // 作为返回值的这个函数调用了之前函数的参数x fmt.Println(x) } }
举例说明:
首先有一个函数f1,它的参数是一个不带参数和返回值的函数:
func f1(f func()) { fmt.Println("this is in f1") f() }
然后有一个函数f2,它的参数是两个整型的变量
func f2(x, y int) { fmt.Println("this is in f2") fmt.Println(x + y) }
此时如果我们需要将f2传入f1中执行,就不能直接f1(f2),因为这样会产生类型不匹配的问题。
所以此时我们构造一个闭包函数f3,他的传入的参数是两个整型变量,这两个变量作为f2的入口参数,然后返回一个没有参数的函数作为返回值,这个返回值就是f1的入口参数
func f3(x, y int) func() { fmt.Println("this is in f3") retFunc := func() { //这个就是返回的函数 f2(x, y) //在返回的函数中调用之前的函数的参数 } return retFunc } func main() { f := f3(1, 2) f1(f) }
此时在main函数中的f的类型为一个不带参数的函数,他就可以作为f1的入口参数了
输出的结果为:
this is in f3
this is in f1
this is in f2
3
再看另一个例子,对于同一次声明的闭包的变量,他们会共用公有的变量
首先定义一个函数闭包,他返回两个函数,这两个函数有一个参数一个返回值,分别代表加和减,主函数传入的参数为base,是返回的两个函数的公共变量
func calc(base int) (func(int) int, func(int) int) { add := func(x int) int { base += x return base } sub := func(x int) int { base -= x return base } return add, sub }
函数calc中的add和sub的作用就是分别对base进行加和减x
然后在main函数中使用这个函数闭包
func main() { add1, sub1 := calc(10) // 因为add1和sub1是同一次初始化的,所以他们共用公共变量base // 下面3次运算add和sub都是base=10的基础上一直计算,并且上一次对base更改的值会在下一次运算中生效 fmt.Println(add1(1), sub1(2)) //11 9 fmt.Println(add1(3), sub1(4)) //12 8 fmt.Println(add1(5), sub1(6)) //13 7 add2, sub2 := calc(20) // add2和sub2不是和add1与sub1同一次定义,所以他们不是共用的公共变量 // 此时是新初始化的公共变量base=20 fmt.Println(add2(1), sub2(2)) //21 19 fmt.Println(add2(3), sub2(4)) //22 18 fmt.Println(add2(5), sub2(6)) //23 17 // 也就是说闭包会在一定程度上面延长局部变量的生命周期 }
从上面的代码可以看出,函数闭包延长了函数中的局部变量的生命周期,上面的例子中,被延长的变量就是base。
最后一句话总结Go中的闭包,闭包就是一个函数的返回值是一个函数,并且作为返回值的函数能够调用这个函数中的局部变量,这些局部变量相当于返回函数的外部变量。
以上是关于Go语言闭包的主要内容,如果未能解决你的问题,请参考以下文章