Go函数是一等公民

一等公民 #

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函数
  • 排序函数
  • 回调函数
  • 函数柯里化
  • 合成函数

进一步阅读 #