Go-函数作为参数传递

724 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

Go-函数作为参数传递

编码过程中业务需要将一个函数,作为参数传递到函数内部。 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