高阶函数
对高阶函数的定义是这个函数至少做到以下的某一项的功能:
- 以一个或者多个函数作为参数
- 返回一个函数作为其结果
将函数作为参数传递给其他函数
package main import ( "fmt" ) func simple(a func(a, b int) int) { fmt.Println(a(60, 7)) } func main() { f := func(a, b int) int { return a + b } simple(f) }
我们定义一个函数 simple
函数,它接收两个 int 参数,并返回一个 int 参数,然后把匿名函数传给变量 f
,然后把 f 作为参数传递给 simple
函数,最终这个程序将打印 67
输出:
67
从其他函数中返回函数
现在让我们重写上面的程序,从 simple
函数中返回一个函数:
package main import ( "fmt" ) func simple() func(a, b int) int { f := func(a, b int) int { return a + b } return f } func main() { s := simple() fmt.Println(s(2022, 60)) }
运行该程序,得到结果;
2082
闭包
闭包是匿名函数的一种特殊情况。闭包是匿名函数,它访问定义在函数主体之外的变量。
代码如下:
package main import ( "fmt" ) func main() { a := 2022 func() { fmt.Println("a = ", a) }() }
每个闭包都与它自己周围的变量绑定。让我们通过一个简单的例子来理解这意味着什么。
package main import ( "fmt" ) func appendStr() func(string) string { t := "Hello" c := func(b string) string { t = t + " " + b return t } return c } func main() { a := appendStr() b := appendStr() fmt.Println(a("World")) fmt.Println(b("Everyone")) fmt.Println(a("Gopher")) fmt.Println(b("!")) }
在上面的程序中,appendStr
函数返回一个闭包。这个闭包被绑定到变量 t
上,变量 a
和 b
是闭包,被绑定到它们自己的值 t
上。
我们传递参数 World
给 a
,然后 a
的值变成了 Hello World
。
传递参数 Everyone
给 b,然后 b
的值变成了 Hello Everyone
。
Hello World Hello Everyone Hello World Gopher Hello Everyone !
闭包通常也是支持嵌套和 defer 工作的方法。在下面的例子中,我们可以看到一个允许我们嵌套工作的函数闭包:
package main import ( "fmt" "sort" ) func main() { input := []string{"foo", "bar", "baz"} var result []string // closure callback func() { result = append(input, "abc") result = append(result, "def") sort.Sort(sort.StringSlice(result)) }() fmt.Println(result) }
运行结果:
[abc bar baz def foo]