4

私は defn の役割について少し困惑しています。fn が無名関数のみを生成する場合、def と fn の機能を組み合わせた構造が必要であることは理解できますが、fn は名前付き関数も作成できます。少なくとも repl では、その使用法が defn とどのように異なるのかわかりません。

4

2 に答える 2

6

に名前記号を指定するとfn関数定義内で関数オブジェクト自体にバインドされるだけです。これは、無名関数が自分自身を呼び出せるようにするためです ( Clojure - 特殊フォーム)。

したがってfn、グローバルにアクセス可能な名前にバインドされた関数を作成するには、使用する必要があります

(def somename 
    (fn ...body...

これはdefn単なるショートカットです。

(defn somename 
    ...body...

あなたのコメントに応えて、新鮮なreplから:

Give me some Clojure:
> (fn foo [] (+ 1 3))
#<sandbox31764$eval31779$foo__31780 sandbox31764$eval31779$foo__31780@12eae8eb>
> (foo)
java.lang.RuntimeException: Unable to resolve symbol: foo in this context
> (defn foo [] (+ 1 3))
#'sandbox31764/foo
> (foo)
4
>  

ご覧のとおり、Var にバインドされていないため、 でfoo作成された関数を呼び出すことはできません。fn

于 2013-07-25T14:54:37.903 に答える
1

主な違いはdefn、グローバル名を作成するのに対しfn、レキシカル ネームのみを作成することです。グローバル名も var です。これは、最終的に で作成されるためdefです。無名関数に付けることができる名前は var ではなく、その関数のスコープ内でのみ使用できます。これは主に、関数を再帰的にできるようにするためです。

于 2013-07-25T14:54:21.840 に答える