我是新來的Clojure,和我見過這樣寫匿名函數:Clojure中的匿名函數的fn和#語法有區別嗎?
(fn [x] (* x x))
也喜歡:
#(* % %)
顯然,第二是更簡潔。有沒有相關的區別?每種匿名函數都可以用哪種風格表示?還有更慣用的嗎?
與此問題相關,我無法確定如何將(fn [x] [x x])
轉換爲後一種語法。我希望有一個指向文檔的指針來澄清這種情況。
我是新來的Clojure,和我見過這樣寫匿名函數:Clojure中的匿名函數的fn和#語法有區別嗎?
(fn [x] (* x x))
也喜歡:
#(* % %)
顯然,第二是更簡潔。有沒有相關的區別?每種匿名函數都可以用哪種風格表示?還有更慣用的嗎?
與此問題相關,我無法確定如何將(fn [x] [x x])
轉換爲後一種語法。我希望有一個指向文檔的指針來澄清這種情況。
最重要的區別是:
(fn ...)
可以被嵌套,#()
不能(fn [x y] ..)
或類似的,更好的名字你的參數,而不是使用%
,%2
,%3
等(fn ...)
命名函數以用於遞歸使用,例如(fn fib [n] (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
#()
是一個閱讀器宏而不是常規的Clojure格式,因此代碼生成/操作更簡單(fn [...] ...)
。#()
更簡潔。但是,如果這是一個重要的考慮因素,你可能有你的優先次序錯了:-)個人我的建議是:
(fn [...] ...)
#()
只有很短的直列功能,例如(map #(+ 2 %) (range 10))
(comp func1 func2)
或(partial func param1 param2)
等另一個限制值得一提(I不知道我是否可以/應該編輯你的響應)是'fn'允許你命名你的函數,以便它們可以在body中被引用,如下所示:'(def fact(fn f [x](if (= 1 x)1(* x(f(dec x))))))' –
真的很欣賞'comp'和'partial'的建議。我想知道這些是否存在,並在Haskell中表示讚賞。 –
從docs,我認爲這是最相關的差異:
習慣使用將是非常短暫的一次性的映射/過濾FNS等。
#()表單不能嵌套。
另一件事是,如果你需要命名參數,fn是一個更好的選擇。對於#(),您將使用%或更多的參數,如%1,%2等等(還有%&)。
另一個SO回答(Common programming mistakes for Clojure developers to avoid)提到#([% %])
擴展爲fn [%] ([% %])
(注意括號中),這將導致一個ArityException。
您可以通過#(vector % %)
來解決此限制。
不能告訴你我因爲這個浪費了多少時間。 – Bill
#()沒有隱含的do。 (fn [] ...)。 – Bill
詳細說明@ Bill的評論:http://stackoverflow.com/questions/12534287/why-does-this-anonymous-function-starting-with-println-result-in-a-nullpointerex – noahlz