Go函数式编程的闭包和装饰器设计模式


函数式编程的准则:

不依赖外部的数据,也不改变外部数据的值,而是返回一个新的值。
func inc(v int ) int {
     return v+1 
} 

在面向对象编程中,我们传递的是对象,在函数式编程中,传递的是函数,函数可以作为另一个函数的参数或返回值、可以赋值给一个变量。

闭包经常用在函数式编程中,闭包只是在形式和表现上像函数,但实际上它并不是函数。函数是由可执行代码组成,在执行时不会发生变化,而闭包在不同的引用环境会有不同的表现。

函数式编程中至少要满足其中一个条件:

接受一个或多个函数作为输入参数
输出一个函数

Go支持匿名函数,即可以将函数作为普通变量使用:在函数中传递、赋值给变量。

package main
import  "fmt"
func adder() func(int) int {
   sum := 0
   innerfunc := func(x int) int {
      sum += x
      return sum
   }
   return innerfunc
}

func main(){
   add := adder()
   for i := 0; i < 5; i++ {
      fmt.Println(add(i))
   }
 
 
复制代码
./hello 
0
1
3
6
10
复制代码

Go可以在函数内部定义匿名函数,adder中定义了一个匿名函数,然后赋值给innerfunc变量,最后将其作为返回值。

for循环中每次通过不同参数调用adder函数时(不同引用环境),匿名函数引用了外层的局部变量sum,由于外部变量的作用域而没有被释放。

复制代码
package main
import  "fmt"
func adder() func(int) int {
   sum := 0
   innerfunc := func(x int) int {
      sum += x
      return sum
   }
   return innerfunc
}

func main(){
   add := adder()
   for i := 0; i < 5; i++ {
      fmt.Println(add(i))
   }
   add2 := adder()
   for i := 0; i < 5; i++ {
      fmt.Println(add2(i))
   }
}
 
复制代码
 
./hello 
0
1
3
6
10
0
1
3
6
10
package main
import "fmt"
type funcHander func(string)

func decorator(f func(string)) func(string){
   return func(s string) {
      f(s)
   }
}

func run(name string){
   fmt.Println(name + " run")
}
func talk(name string){
   fmt.Println(name + " talk")
}
//管道操作,遍历多个子修饰器,运行对应的代码
func Decorate(name string, ds ...funcHander){
   for _,a := range ds{
      decorator(a)(name)
   }
}

func main(){
   decorator(run)("zhangsan") //通过装饰器调用
   Decorate("lisi",run, talk) //通过装饰器管道调用
}
./hello
zhangsan run
lisi run
lisi talk
 
原文地址:https://www.cnblogs.com/dream397/p/15036535.html