函數(shù)式編程是一種編程范式,就是跟我們上大學(xué)的時候,大學(xué)老師總是掛在嘴邊的“面向?qū)ο蟆保懊嫦蜻^程”等等是一個東東。
既然是函數(shù)式編程編程,那么“函數(shù)”是少不了的了。能夠?qū)崿F(xiàn)“函數(shù)式編程”的語言,函數(shù)必須是該語言的“一等公民”,即函數(shù)是可以直接聲明調(diào)用的,而不是需要在類中聲明成方法(沒錯,我說的是Java)。
例如,python中:
def f(x):
return x+3
g=f
print g(4)
#output 7
例子中,f直接就代表了函數(shù)f(x),可以賦值給其他的變量。這就是“一等公民”。
當(dāng)然,僅僅是滿足這一點是不行,基本需要如下幾點:
1,函數(shù)是“一等公民”
2,函數(shù)可以作為函數(shù)的返回值
3,函數(shù)可以做函數(shù)的參數(shù)
高階函數(shù)
前面已經(jīng)說過,函數(shù)式編程中函數(shù)是可以作為函數(shù)的返回值和參數(shù)的,那么滿足這兩個條件之一的函數(shù),就是高階函數(shù)。鑒于數(shù)學(xué)和計算機(jī)科學(xué)的基友性質(zhì),函數(shù)和高階函數(shù)的概念都是從數(shù)學(xué)中引申而來的。舉一個在令我們頭疼的微積分課的例子,有個老是出現(xiàn)的玩意就是高階函數(shù),那玩意叫導(dǎo)數(shù)。
python高階函數(shù)示例:
def f(x):
return x + 3
def g(function, x):
return function(x) * function(x)
print g(f, 7)
--
閉包
曾經(jīng)面試官讓我解釋“閉包”,我只說一句“里面的可以用外面的,外面的不能用里面的。”用更通俗易懂的話來說,就是“你的就是我的,我的還是我的。”
這里牽扯出一個作用域的問題,就是我們在寫很多語言的時候,那個“{}”(大python中用縮進(jìn))。
def f(x):
def g(x):
return x+3
return x
print g(4)
會輸出什么?會是7嗎?
No,會報錯。找不到g函數(shù),只有在函數(shù)f的作用域(函數(shù)體內(nèi))才能調(diào)用它。
但是,函數(shù)式編程的時候,是可以將函數(shù)作為返回值的,所以可以通過這樣的方式來使用:
def f():
def g(x):
return x+3
return g
p=f()
print p(4)
#output 7
ok,完了。就這樣完了?沒錯,太過深奧的概念不需要說太多,說了有時候也無法理解。了解了函數(shù)式編程基本概念和高階函數(shù),就可以非常飄逸的運用起來,比如“裝飾設(shè)計”。
裝飾設(shè)計
在日常工作中,我們寫好了一個函數(shù),結(jié)果產(chǎn)品經(jīng)理屁顛屁顛過來說,改需求了(萬惡產(chǎn)品狗)!這個函數(shù)運行時得加上日志,那么沒經(jīng)驗的時候的做法,就是苦逼到這個函數(shù)里面改代碼,結(jié)果牽一發(fā)而動全身,整個模塊都要改!!!
設(shè)計模式中裝飾模式,可以很靈活的解決這個問題。如果利用高階函數(shù)的話,則可以更好的實現(xiàn)裝飾模式。
def f(x):
return x+3
def logo(f,x):
print "函數(shù)f開始計算"
f(x)
print "函數(shù)f計算完畢"
print logo(f,3)
#output
函數(shù)f開始計算
6
函數(shù)f計算完畢