编码过程中业务需要将一个函数,作为参数传递到函数内部。Go 语言的匿名函数是一个闭包(Closure)
闭包指的是引用了自由变量的函数(未绑定到特定对象的变量,通常在匿名函数外定义),被引用的自由变量将和这个函数一同存在。
f := func() {
var i int = 1
fmt.Printf("i, j: %d, %d\n", i, j)
}
即使创造它的上下文环境也不会被释放(比如传递到其他函数或对象中)。或者通俗点说,「闭」的意思是「封闭外部状态」,即使外部状态已经失效,闭包内部依然保留了一份从外部引用的变量。
闭包的价值在于可以作为函数对象或者匿名函数,对于类型系统而言,这意味着这个对象不仅要表示数据还要表示代码. 就是说这些函数可以存储到变量中作为参数传递给其他函数,能够被函数动态创建和返回。
闭包内部声明的局部变量无法从外部修改,从而确保了安全性(类似类的私有属性):
f := func() {
var i int = 1
fmt.Printf("i, j: %d, %d\n", i, j)
}
声明一个外部函数的参数为函数类型,然后定义一个闭包并赋值给指定变量,再将这个变量传递到外部函数中。
func funcParam(param func(int, int) int) int {
fmt.Printf("param type: %T\n", funcParam)
return param(1, 2)
}
func TestFuncParam(t *testing.T) {
add := func(x, y int) int {
return x + y
}
result := funcParam(add)
fmt.Printf("add type: %T\n", add)
fmt.Println(result)
}
执行结果:
=== RUN TestFuncParam
param type: func(func(int, int) int) int
add type: func(int, int) int
3
--- PASS: TestFuncParam (0.00s)
PASS
闭包作为函数返回值
func addfunc(a int) func(b int) int {
return func(b int) int {
return a + b
}
}
func TestFucReturn(t *testing.T) {
f := addfunc(1)
fmt.Println(f(2))
}
执行结果:
=== RUN TestFucReturn
3
--- PASS: TestFucReturn (0.00s)
PASS