函数式编程的准则:
不依赖外部的数据,也不改变外部数据的值,而是返回一个新的值。
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