這篇文章從下面幾個(gè)方面學(xué)習(xí)函數(shù)式編程:
成都創(chuàng)新互聯(lián)公司于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站制作、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢想脫穎而出為使命,1280元都勻做網(wǎng)站,已為上家服務(wù),為都勻各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:189820811081、數(shù)學(xué)公式和函數(shù)式編程有什么關(guān)系
舉個(gè)簡單例子吧,數(shù)學(xué)中有一個(gè)概念叫做映射(y=f(x)),說的通俗一點(diǎn)就是函數(shù)啦。而最熟悉的應(yīng)該就是二次函數(shù)(拋物線y=a*x*x+b*x+c)
現(xiàn)在coding實(shí)現(xiàn)求拋物線上某一點(diǎn)的值,我們知道a,b,c是參數(shù),x是自變量,y是因變量,如果是以前,我也許會(huì)這么實(shí)現(xiàn)(為了紀(jì)念我許久未寫的c++,還是用c++來寫一下)
double getParabola(double a,double b,double c,double x) { return a*x*x+b*x+c; }
問題一、給定拋物線,求x=2,x=3,x=4時(shí)的值,就是下面的做法了
resultA = getParabola(a,b,c,2) resultB = getParabola(a,b,c,2) resultC = getParabola(a,b,c,2)
這在程序中,是很正常的做法。但是,如果從數(shù)學(xué)的角度來看,有沒有辦法變得符合數(shù)學(xué)公式思維呢?以下是我的另外一種實(shí)現(xiàn)(這里用go來實(shí)現(xiàn)哈,因?yàn)閏++我知道怎么寫),
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 }
然后,同樣是對于問題一,解決方案如下
parabola := getParabola(a,b,c) resultA := parabola(2) resultB := parabola(3) resultC := parabola(4)
是不是跟求函數(shù)值一樣?所以,數(shù)學(xué)關(guān)系在函數(shù)式編程中得到了很好的體現(xiàn)。
2、函數(shù)式編程有什么特點(diǎn),go支持了哪些概念
函數(shù)式編程有三大特性
1、變量的不可變性: 變量一經(jīng)賦值不可改變。如果需要改變,則必須復(fù)制出去,然后修改。 go中,string變量一經(jīng)賦值,不可以像c++那樣,c[2]='a'這樣的修改,而是要顯式轉(zhuǎn)化為[]byte,然后進(jìn)行修改。但是已經(jīng)是另外一塊內(nèi)存了。
2、函數(shù)式一等公民: 函數(shù)也是變量,可以作為參數(shù),返回值等在程序中進(jìn)行傳遞。 這個(gè)特性,c++和go應(yīng)該都是支持的。
3、尾遞歸:遞歸的概念在斐波那契數(shù)列的時(shí)候,就學(xué)習(xí)過了。如果遞歸很深的話,堆棧可能會(huì)爆掉,并導(dǎo)致性能大幅度下降。而尾遞歸優(yōu)化技術(shù),編譯器如果支持的話,可以在每次遞歸時(shí)重用stack(尾遞歸表示遞歸調(diào)用發(fā)生在最后一步,這個(gè)時(shí)候,之前的結(jié)果都作為參數(shù)傳遞給最后一步的調(diào)用,所以之前的狀態(tài)就沒有任何作用了,所以可以重用stack)。
函數(shù)式編程常用技術(shù)
1、map&reduce&filter
map用于對每一個(gè)輸入,調(diào)用同一個(gè)函數(shù),產(chǎn)生一個(gè)輸出,比如c++中的for_each,hadoop里面的map,python的map等。
reduce用于對每一個(gè)輸入,加上上一個(gè)輸出,得到下一個(gè)輸出,比如python和hadoop中的reduce,
filter用于做過濾,比如c++的count_if等。
2、遞歸
3、pipeline
把函數(shù)實(shí)例放到一個(gè)數(shù)組或是列表中,然后把數(shù)據(jù)傳給這個(gè)action list,輸入順序地被各個(gè)函數(shù)所操作(意思是每一個(gè)函數(shù)的輸出,作為另外一個(gè)函數(shù)的輸入,數(shù)據(jù)是流動(dòng)的,計(jì)算是固定的,類似storm的概念),最終得到我們想要的結(jié)果。
4、其他(有待進(jìn)一步學(xué)習(xí))
3、函數(shù)式編程與運(yùn)行效率
函數(shù)式編程最重要的一個(gè)概念就是函數(shù)式一等公民,函數(shù)跟變量是一樣的。可以作為參數(shù),返回值等。不贊成使用賦值語句,所以比較多的使用遞歸,所以函數(shù)式編程效率肯定會(huì)比較低。
最近我用的比較多的是閉包,閉包的概念就是一個(gè)環(huán)境(一個(gè)或多個(gè)變量)加上一個(gè)函數(shù),每一次對閉包表達(dá)式求值,都得到一個(gè)隔離的結(jié)果,這跟普通函數(shù)是不一樣的,普通函數(shù)就是一段可執(zhí)行的代碼,只要入口確定了,調(diào)用的位置也就確定了。舉個(gè)例子,上面拋物線的例子,調(diào)用
a:=getParabola(0.2,0.1,0.3) b:=getParabola(0.1,0.1,0.4)
得到的是兩條拋物線。之所以我覺得效率會(huì)降低,是因?yàn)殚]包本身就是一個(gè)求值賦值的過程,涉及到變量的創(chuàng)建銷毀。當(dāng)然,我沒有實(shí)際去測試性能。如果后續(xù)發(fā)行server效率降低,也許這是一個(gè)需要考慮的地方。
以上就是從go語言閉包談函數(shù)式編程的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!