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语言闭包的主要内容,如果未能解决你的问题,请参考以下文章

go语言中的闭包

015_go语言中的闭包

05. Go 语言函数

Go语言开发Go语言闭包

Go语言学习匿名函数与闭包

go语言学习--go中闭包