我们今天说的Go中的函数式编程主要是体现在闭包上面的,比如
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++ {
fmt.Printf("0 + 1 + ... + %d = %d\n", i, a(i))
}
}
我们首先对比两个概念
函数式编程 vs 函数指针
- 函数是一等公民:参数,变量,返回值都可以是函数(C++只有函数指针 Java的函数不能作为参数)
- 高阶函数
- 函数->闭包
那么什么是正统的函数式编程呢?
- 不可变性:不能有状态,只有常量和函数
- 函数只能有一个参数
Go不会在正统上大作文章的,😄
上面这张图呀,很清楚的表达了闭包的概念,自由变量就是外面函数的变量相当于sum。我们来看一下正统的函数式编程是怎么做的呢,我们这边马马虎虎的实现一把!!!!
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 := adder() is trivial and also works.
a := adder2(0)
for i := 0; i < 10; i++ {
var s int
s, a = a(i)
fmt.Printf("0 + 1 + ... + %d = %d\n",
i, s)
}
}
// 这样的写法可能不是很好懂,但是这种写法没有自由变量在里面,会更安全一些。
最后我们来看一下其他语言是怎么实现闭包的。
Python实现的方式
def adder(value):
sum = 10
def sumAll(value):
nonlocal sum
sum = sum+value
return sum
return sumAll
if __name__ =='__main__':
result = adder(sum)
# 打印环境变量
print(result.__closure__[0].cell_contents)
for x in range(10):
print(result(x))
Python是原生支持闭包的,你可以使用closure查看闭包内容
C++实现闭包的方式
auto adder(){
auto sum = 0;
return [=] (int value) mutable {
sum += value;
return sum;
};
}
// c++ 11及以后:支持闭包,我没有学过c++这里给大家贴出来,只是让大家感受一把!!!
ok, 怎么样闭包掌握的怎么样了呢😄!!!!继续加油吧!!!!下面还有函数式编程的干货,敬请期待把!!!!!