溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

go語言中的函數(shù)式編程

發(fā)布時(shí)間:2020-05-22 18:02:13 來源:億速云 閱讀:275 作者:鴿子 欄目:編程語言

這篇文章從下面幾個(gè)方面學(xué)習(xí)函數(shù)式編程:

1、數(shù)學(xué)公式和函數(shù)式編程有什么關(guān)系

舉個(gè)簡(jiǎn)單例子吧,數(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
}

然后,同樣是對(duì)于問題一,解決方案如下

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用于對(duì)每一個(gè)輸入,調(diào)用同一個(gè)函數(shù),產(chǎn)生一個(gè)輸出,比如c++中的for_each,hadoop里面的map,python的map等。

reduce用于對(duì)每一個(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ù),每一次對(duì)閉包表達(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í)際去測(cè)試性能。如果后續(xù)發(fā)行server效率降低,也許這是一個(gè)需要考慮的地方。

以上就是從go語言閉包談函數(shù)式編程的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注億速云其它相關(guān)文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI