13

私はclojureを初めて使用し、次のように記述された無名関数を見てきました。

(fn [x] (* x x))

そしてまた好き:

#(* % %)

明らかに、2番目はより簡潔です。関連する違いはありますか?すべての無名関数をどちらのスタイルでも表すことができますか?もう1つ慣用的で​​すか?

(fn [x] [x x])この質問に関連して、後者の構文に変換する方法を決定できませんでした。この状況を明確にするドキュメントへのポインタをいただければ幸いです。

4

3 に答える 3

21

最も重要な違いは次のとおりです。

  • (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)
于 2012-10-02T02:23:18.463 に答える
5

もう 1 つの SO の回答 ( Clojure 開発者が避けるべき一般的なプログラミングの間違い)は、ArityException を引き起こす (括弧に注意してください) に#([% %])展開することについて言及しています。fn [%] ([% %])

#(vector % %)この制限を回避するために行うことができます。

于 2012-10-02T02:27:54.773 に答える
2

docsから、これらが最も関連性のある違いだと思います:

慣用的に使用されるのは、非常に短い 1 回限りのマッピング/フィルター fns などです。

#() フォームはネストできません。

別のことは、名前付きパラメーターが必要な場合は、 fn がより良いオプションです。#() の場合は % を使用するか、複数のパラメーターの場合は %1、%2 など (%&) を使用します。

于 2012-10-02T02:14:43.943 に答える