从go语言闭包谈函数式编程


本文摘自php中文网,作者尚,侵删。

这篇文章从下面几个方面学习函数式编程:

1、数学公式和函数式编程有什么关系

举个简单例子吧,数学中有一个概念叫做映射(y=f(x)),说的通俗一点就是函数啦。而最熟悉的应该就是二次函数(抛物线y=a*x*x+b*x+c)

现在coding实现求抛物线上某一点的值,我们知道a,b,c是参数,x是自变量,y是因变量,如果是以前,我也许会这么实现(为了纪念我许久未写的c++,还是用c++来写一下)

1

2

3

double getParabola(double a,double b,double c,double x) {

     return a*x*x+b*x+c;

}

问题一、给定抛物线,求x=2,x=3,x=4时的值,就是下面的做法了

1

2

3

resultA = getParabola(a,b,c,2)

resultB = getParabola(a,b,c,2)

resultC = getParabola(a,b,c,2)

这在程序中,是很正常的做法。但是,如果从数学的角度来看,有没有办法变得符合数学公式思维呢?以下是我的另外一种实现(这里用go来实现哈,因为c++我知道怎么写),

1

2

3

4

5

6

7

8

9

10

11

func getParabola(aa,bb,cc float32){

    var a = aa

    var b = bb

    var c = cc

  

    a := func(x float32) {

           return a*x*x+b*x+c

    }

  

    return a

}

然后,同样是对于问题一,解决方案如下

1

2

3

4

5

parabola := getParabola(a,b,c)

  

resultA := parabola(2)

resultB := parabola(3)

resultC := parabola(4)

是不是跟求函数值一样?所以,数学关系在函数式编程中得到了很好的体现。

2、函数式编程有什么特点,go支持了哪些概念

函数式编程有三大特性

1、变量的不可变性: 变量一经赋值不可改变。如果需要改变,则必须复制出去,然后修改。 go中,string变量一经赋值,不可以像c++那样,c[2]='a'这样的修改,而是要显式转化为[]byte,然后进行修改。但是已经是另外一块内存了。

2、函数式一等公民: 函数也是变量,可以作为参数,返回值等在程序中进行传递。 这个特性,c++和go应该都是支持的。

3、尾递归:递归的概念在斐波那契数列的时候,就学习过了。如果递归很深的话,堆栈可能会爆掉,并导致性能大幅度下降。而尾递归优化技术,编译器如果支持的话,可以在每次递归时重用stack(尾递归表示递归调用发生在最后一步,这个时候,之前的结果都作为参数传递给最后一步的调用,所以之前的状态就没有任何作用了,所以可以重用stack)。

函数式编程常用技术

1、map&reduce&filter

map用于对每一个输入,调用同一个函数,产生一个输出,比如c++中的for_each,hadoop里面的map,python的map等。

reduce用于对每一个输入,加上上一个输出,得到下一个输出,比如python和hadoop中的reduce,

filter用于做过滤,比如c++的count_if等。

2、递归

3、pipeline

把函数实例放到一个数组或是列表中,然后把数据传给这个action list,输入顺序地被各个函数所操作(意思是每一个函数的输出,作为另外一个函数的输入,数据是流动的,计算是固定的,类似storm的概念),最终得到我们想要的结果。

4、其他(有待进一步学习)

3、函数式编程与运行效率

函数式编程最重要的一个概念就是函数式一等公民,函数跟变量是一样的。可以作为参数,返回值等。不赞成使用赋值语句,所以比较多的使用递归,所以函数式编程效率肯定会比较低。

最近我用的比较多的是闭包,闭包的概念就是一个环境(一个或多个变量)加上一个函数,每一次对闭包表达式求值,都得到一个隔离的结果,这跟普通函数是不一样的,普通函数就是一段可执行的代码,只要入口确定了,调用的位置也就确定了。举个例子,上面抛物线的例子,调用

1

2

a:=getParabola(0.2,0.1,0.3)

b:=getParabola(0.1,0.1,0.4)

得到的是两条抛物线。之所以我觉得效率会降低,是因为闭包本身就是一个求值赋值的过程,涉及到变量的创建销毁。当然,我没有实际去测试性能。如果后续发行server效率降低,也许这是一个需要考虑的地方。

更多go语言知识请关注PHP中文网go语言教程栏目。

以上就是从go语言闭包谈函数式编程的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Golang xml 解析神器 etree 转载自“北极熊博客”

Go get下载包失败问题

Go微服务入门到容器化实践,落地可观测的微服务电商项目

Go strings

一周 Go world 新鲜事

Golang基础数据类型-浮点型

beeGo-vue-admin基于当前流行技术组合的前后端rbac管理系统:Go1.15.x+beeGo2.x+jwt+redis+mysql8+vue 的前后端分离系统,权限控制采用 rbac,支持

聊聊nacos-coredns-plugin的servermanager

Golang两个协程交替输出

Golang网络数据传输过程中的binary.read与unsafe.pointer指针强转分析

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...