4

我对defn的作用有点疑惑。如果 fn 只生成匿名函数,我可以理解需要一个结合 def 和 fn 功能的构造,但 fn 也可以创建命名函数。至少在 repl 中,我看不出这种用法与 defn 有何不同。

4

2 回答 2

6

当您向 提供名称符号时fn,它仅在函数定义内绑定到函数对象本身。这是为了允许匿名函数调用自己(Clojure - 特殊形式)。

因此,要创建一个fn绑定到全局可访问名称的函数,您必须使用

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

defn只是一个捷径。

(defn somename 
    ...body...

作为对您的评论的回应,来自一个新的回复:

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
>  

如您所见,我无法调用使用foo创建的函数fn,因为它未绑定到 Var。

于 2013-07-25T14:54:37.903 回答
1

主要区别在于defn创建一个全局名称,而 wheresfn只创建一个词法名称。全局名称也是一个 var,因为它最终是用def. 您可以给匿名函数的名称不是 var,并且仅在该函数的范围内。这主要是因为函数可以是递归的。

于 2013-07-25T14:54:21.840 回答