首頁 >後端開發 >Golang >從go語言閉包談函數式程式設計

從go語言閉包談函數式程式設計

尚
轉載
2020-01-07 17:44:412729瀏覽

從go語言閉包談函數式程式設計

這篇文章從下面幾個面向學習函數式程式設計:

1、數學公式和函數式程式設計有什麼關係

#舉個簡單例子吧,數學中有一個概念叫做映射(y=f(x)),說的通俗一點就是函數啦。而最熟悉的應該就是二次函數(拋物線y=a*x*x b*x c)

現在coding實現求拋物線上某一點的值,我們知道a,b,c是參數,x是自變量,y是因變量,如果是以前,我也許會這麼實現(為了紀念我許久未寫的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時的值,就是下面的做法了

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

這在程式中,是很正常的做法。但是,如果從數學的角度來看,有沒有辦法變得符合數學公式思考呢?以下是我的另一個實作(這裡用go來實作哈,因為c 我知道怎麼寫),

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)

是不是跟求函數值一樣?所以,數學關係在函數式程式設計中得到了很好的體現。

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、函數式程式設計與運行效率

函數式程式設計最重要的一個概念就是函數式一等公民,函數跟變數是一樣的。可以作為參數,傳回值等。不贊成使用賦值語句,所以比較多的使用遞歸,所以函數式程式設計效率一定會比較低。

最近我用的比較多的是閉包,閉包的概念就是一個環境(一個或多個變數)加上一個函數,每一次對閉包表達式求值,都得到一個隔離的結果,這跟普通函數是不一樣的,普通函數就是一段可執行的程式碼,只要入口確定了,呼叫的位置也就確定了。舉個例子,上面拋物線的例子,呼叫

a:=getParabola(0.2,0.1,0.3)
b:=getParabola(0.1,0.1,0.4)

得到的是兩條拋物線。之所以我覺得效率會降低,是因為閉包本身就是一個求值賦值的過程,牽涉到變數的創建銷毀。當然,我沒有實際去測試性能。如果後續發行server效率降低,也許這是一個需要考慮的地方。

更多go語言知識請關注PHP中文網go語言教學專欄。

以上是從go語言閉包談函數式程式設計的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除