首页 > 编程笔记

Go语言闭包函数的用法

在 Go 语言中,引用外部变量的函数称为闭包,即使已经离开了引用环境也不会被释放或者删除,在闭包中可以继续使用这个变量,简单可以理解为:
函数+引用环境=闭包
同一个函数与不同引用环境组合可以形成不同的实例,如下图所示。


图 1 闭包组合方式

如果单从概念上理解闭包是十分困难的,我们不妨结合实例进行分析,代码如下:
package main

import "fmt"

// 闭包 = 函数 + 引用环境
func adder() func(int) int {
     // 定义函数adder(),返回值为匿名函数func(int) int
     var x int = 10
     // 匿名函数作为函数返回值
     return func(y int) int {
          x += y
          return x
     }
}

func main() {
     // 函数adder()是一个闭包
     // 函数adder()内部有变量x(引用环境)和匿名函数
     // 匿名函数引用了其外部作用域中的变量x
     // 在函数adder()的生命周期内,变量x一直有效
     f := adder()
     fmt.Println(f(10))
     fmt.Println(f(20))
     f1 := adder()
     fmt.Println(f1(2000))
     fmt.Println(f1(5000))
}
运行上述代码,运行结果为:

20
40
2010
7010

结合代码与运行结果分析得知:

1) 自定义函数 adder() 实现闭包功能,函数内部定义变量 x 和匿名函数,并且匿名函数作为函数返回值。

2) 匿名函数设置参数 y 和引用自定义函数 adder() 的变量 x,在匿名函数内部对变量 x 进行赋值计算,最后将变量 x 的值作为返回值。

3) 在主函数 main() 中调用函数 adder(),函数返回值以变量 f 表示,变量 f 是匿名函数的函数变量,通过函数变量 f 完成匿名函数的调用。

4) 由于函数变量 f 是调用函数 adder() 产生的,当函数变量 f 调用匿名函数时,匿名函数能使用函数 adder() 定义的变量 x。

5) 从代码的 f(10) 看到,第一次调用匿名函数的时候,变量 x 的初始值为 10,参数 y 的值设为 10,所以程序输出 20;第二次调用匿名函数的时候,变量 x 的值经过第一次调用已经变为 20,参数 y 的值设为 20,所以程序输出 40。函数变量 f 每调用一次都会改变变量 x 的值。

6) 匿名函数除了使用函数 adder() 定义的变量 x 之外,还可以使用函数 adder() 的参数作为引用环境。

根据闭包原理可以实现很多实用性功能,比如在 Web 开发中,某些网页需要用户登录才能查看,用户登录验证可以使用闭包实现。

推荐阅读