文章首发于:clawhub.club
这篇文章纯纯的借鉴加复制,参考了Go 系列教程 —— 33. 函数是一等公民(头等函数) 虽然说java现在也支持了链式编程,但是对头等函数方面还是很陌生的。
定义 支持头等函数(First Class Function)的编程语言,可以把函数赋值给变量,也可以把函数作为其它函数的参数或者返回值。Go 语言支持头等函数的机制。
匿名函数 没有名称的函数称为匿名函数(Anonymous Function),要调用一个匿名函数,可以不用赋值给变量。还可以向匿名函数传递参数。
1 2 3 4 5 6 7 8 9 10 11 package mainimport ( "fmt" ) func main () { func (n string ) { fmt.Println("Welcome" , n) }("Gophers" ) }
用户自定义的函数类型 和定义结构体一样,可以定义函数类型,就像HandlerFunc一样。
1 2 type HandlerFunc func (*Context)
参考个更简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "fmt" ) type add func (a int , b int ) int func main () { var a add = func (a int , b int ) int { return a + b } s := a(5 , 6 ) fmt.Println("Sum" , s) }
高阶函数 wiki 把高阶函数(Hiher-order Function)定义为:满足下列条件之一的函数 :
把函数作为参数,传递给其它函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package mainimport ( "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) }
在其它函数中返回函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "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(60 , 7 )) }
闭包 闭包(Closure)是匿名函数的一个特例。当一个匿名函数所访问的变量定义在函数体的外部时,就称这样的匿名函数为闭包。每一个闭包都会绑定一个它自己的外围变量(Surrounding Variable)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport ( "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("!" )) }
头等函数的实际用途 如果我们希望将切片中的所有整数乘以 5,并返回出结果,那么通过头等函数可以很轻松地实现。我们把这种对集合中的每个元素进行操作的函数称为 map 函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package mainimport ( "fmt" ) func iMap (s []int , f func (int ) int ) []int { var r []int for _, v := range s { r = append (r, f(v)) } return r } func main () { a := []int {5 , 6 , 7 , 8 , 9 } r := iMap(a, func (n int ) int { return n * 5 }) fmt.Println(r) }
该程序会输出: