函数式编程
- 函数式一等公民:参数,变量,返回值都可以是函数
- 高阶函数:函数的参数也可以是一个函数
- 函数 -> 闭包
func adder() func(int) int {
sum := 0
return func(v int) int {
sum += v
return sum
}
}
func main() {
a := adder()
for i := 0; i < 10; i++ {
// 0 + 1 + ... + 0 = 0
// 0 + 1 + ... + 1 = 1
// 0 + 1 + ... + 2 = 3
// 0 + 1 + ... + 3 = 6
// 0 + 1 + ... + 4 = 10
// 0 + 1 + ... + 5 = 15
// 0 + 1 + ... + 6 = 21
// 0 + 1 + ... + 7 = 28
// 0 + 1 + ... + 8 = 36
// 0 + 1 + ... + 9 = 45
fmt.Printf("0 + 1 + ... + %d = %d\n", i, a(i) )
}
}
15286958675852.jpg上面的代码主要介绍了go 语言中的闭包,在函数返回时,并不是直接返回一个结果,而是返回类似下图结构的一个闭包
正统函数式编程
adder2函数与adder 函数的区别是,adder2会少一个自由变量,但相对来说更不容易阅读一些
type iAdder func(int) (int, iAdder)
func adder2(base int) iAdder {
return func(v int) (int, iAdder) {
return base + v, adder2(base + v)
}
}
func main() {
a := adder2(0)
for i := 0; i < 10; i++ {
var s int
s, a = a(i)
// 0 + 1 + ... + 0 = 0
// 0 + 1 + ... + 1 = 1
// 0 + 1 + ... + 2 = 3
// 0 + 1 + ... + 3 = 6
// 0 + 1 + ... + 4 = 10
// 0 + 1 + ... + 5 = 15
// 0 + 1 + ... + 6 = 21
// 0 + 1 + ... + 7 = 28
// 0 + 1 + ... + 8 = 36
// 0 + 1 + ... + 9 = 45
fmt.Printf("0 + 1 + ... + %d = %d\n", i, s)
}
}
python 中的闭包
python 原生支持闭包
可以使用_closure来查看闭包的内容
def adder():
sum = 0
def f(value):
nonlocal sum
sum += value
return sum
return f
c++的闭包
过去stl或者boost带有类似的库,c++11及以后开始支持闭包
auto adder() {
auto sum = 0;
return [=] (int value) mutable {
sum += value;
return sum;
};
}
java 中的闭包
1.8以后使用Function接口和Lambda表达式来创建函数对象,匿名类或Lambda表达式均支持闭包
Function<Integer, Integer> adder() {
final Holder<Integer> sum = new Holder<>(0);
return (Integer value) -> {
sum.value += value;
return sum.value;
}
}
c# 中的闭包
C# 中可以使用Func来进行闭包
Func<int> adder() {
var sum = 0;
return (int value) => {
sum += value;
return sum;
};
}
闭包的应用
斐波那契数列
func fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b, a + b
return a
}
}
func main() {
f := fibonacci()
fmt.Println(f()) // 1
fmt.Println(f()) // 1
fmt.Println(f()) // 2
fmt.Println(f()) // 3
fmt.Println(f()) // 5
fmt.Println(f()) // 8
}
使用函数遍历二叉树
通过下面的例子我们可以看到,闭包的使用可以减少我们写很多代码
func (node *Node) TraverseFunc(f func(*Node)) {
if node == nil {
return
}
node.Left.TraverseFunc(f)
f(node)
node.Right.TraverseFunc(f)
}
func (node *Node) Traverse() {
node.TraverseFunc(func(node *Node) {
node.Print()
})
fmt.Println()
}
网友评论