大家好,我是對於 Clojure 一無所知的菜鳥小白工程師。
今天我們要來學習 Clojure 中的匿名函數 Fnonynous Functions
。
try Clojure here: https://qa-mktg.codingrooms.com/compiler/clojure/
在Clojure中,函數不一定需要名稱。
沒有名稱的函數,就是所謂的匿名函數(Anonymous Functions)。
我們可以用兩種方式創建匿名函數(fn
&#
)。
第一種方式是使用fn
形式:
(fn [param-list] ;參數列表
function body) ;參數主體
我們來看下面的例子:
((fn [x] (* x 3)) 8)
; => 24
可以發現,我們對待 fn
幾乎和對待 defn
的方式一樣。參數列表和函數主體的運作方式完全相同。我們也可以使用參數解構、剩餘參數等。
我們甚至可以將匿名函數與一個名稱關聯起來:
(def my-special-multiplier (fn [x] (* x 3)))
(my-special-multiplier 12)
; => 36
Clojure 還提供了另一種更簡潔的方法 #
來創建匿名函數。請看下方例子:
#(* % 3)
我們來嘗試應用這個奇怪的函數:
(#(* % 3) 8)
; => 24
我們可以看到,這種語法確實更為簡潔,但也有點奇怪。讓我們來分解一下。
這種匿名函數看起來很像一個函數呼叫,只不過它前面加了一個井號( #
):
;; 函數調用
(* 8 3)
;; 匿名函數
#(* % 3)
我們現在應該可以猜到了,百分比符號(%
)表示傳遞給函數的參數。
如果我們的匿名函數接受多個參數,可以這樣區分它們:%1
,%2
,%3
...等,%
等同於 %1
。我們來看以下例子:
(#(str %1 " and " %2) "cornbread" "butter beans")
; => "cornbread and butter beans"
我們還可以通過 %&
傳遞剩餘參數:
(#(identity %&) 1 "blarg" :yip)
; => (1 "blarg" :yip)
在這種情況下,我們將 identity 函數應用於剩餘參數。Identity 返回它所接收的參數,而不對其進行修改。剩餘參數被存儲為列表,所以函數應用返回所有參數的列表。
如果我們需要寫一個簡單的匿名函數,使用這種風格(#
)是最好的,因為它在視覺上更緊湊。另一方面,如果我們寫的是一個更長、更複雜的函數,這樣的寫法可能會變得難以閱讀。在這種情況下,使用 fn
更適合。
我們今天學習了 Clojure 中的匿名函數(Anonymous Functions
),以及如何定義(fn
&#
)。
在下一章節,我們將開始學習如何將先前學到的內容結合起來,並學習 Clojure 中一些好用的方法。