一等公民 #
Go语言中函数是一等公民(first class),因为它既可以作为变量,也可作为函数参数,函数返回值。Go语言还支持匿名函数,闭包,函数返回多个值。
一等公民特征 #
函数赋值给一个变量 #
func add(a, b int) int {
return a + b
}
func main() {
fn := add
fmt.Println(fn(1, 2)) // 3
}
函数作为返回值 #
func pow(a int) func(int) int {
return func(b int) int {
result := 1
for i := 0; i < b; i++ {
result *= a
}
return result
}
}
func main() {
powOfTwo := pow(2) // 2的x次幂
fmt.Println(powOfTwo(3)) // 8
fmt.Println(powOfTwo(4)) // 16
powOfThree := pow(3) // 3的x次幂
fmt.Println(powOfThree(3)) // 27
fmt.Println(powOfThree(4)) // 81
}
函数作为函数参数传递 #
下面示例中使用匿名函数作为函数参数传递另外一个函数。
func filter(a []int, fn func(int) bool) (result []int) {
for _, v := range a {
if fn(v) {
result = append(result, v)
}
}
return result
}
func main() {
data := []int{1, 2, 3, 4, 5}
// 传递奇数过滤器函子,过滤出奇数
fmt.Println(filter(data, func(a int) bool {
return a&1 == 1
})) // 1, 3, 5
// 过滤出偶数
fmt.Println(filter(data, func(a int) bool {
return a&1 == 0
})) // 2, 4
}
使用闭包函数构建一个生成器 #
生成器指的是每次调用时候总是返回下一序列值。下面演示一个整数的生成器:
func generateInteger() func() int {
ch := make(chan int)
count := 0
go func() {
for {
ch <- count
count++
}
}()
return func() int {
return <-ch
}
}
func main() {
generate := generateInteger()
fmt.Println(generate()) // 0
fmt.Println(generate()) // 1
fmt.Println(generate()) // 2
}
函数式编程 #
函数式编程(functional programming)是一种编程范式,其核心思想是将复杂的操作采用函数嵌套、组合调用方式来处理。函数式编程一大特征是函数是一等公民,Go语言中函数是一等公民,但是由于其不支持泛型,Go语言中采用函数式编程有时候是无法通用性的。比如上面的过滤器示例,当想要支持过滤int64类型的,就需要重写一遍或者传递interface{}参数。
高阶函数 #
高阶函数(Higher-order function)指的是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入
- 输出一个函数
高阶函数是函数式编程中常用范式,常见使用案例有:
- 过滤器
- apply函数
- 排序函数
- 回调函数
- 函数柯里化
- 合成函数