使用 Clojure 1.2,此代码有效
(defn A [] (fn [a] (+ a 2)))
(println ((A) 0))
(println (eval (list (A) 0)))
但以下代码在第三行失败
(defn A [b] (fn [a] (+ a b)))
(println ((A 3) 0))
(println (eval (list (A 3) 0)))
为什么?
使用 Clojure 1.2,此代码有效
(defn A [] (fn [a] (+ a 2)))
(println ((A) 0))
(println (eval (list (A) 0)))
但以下代码在第三行失败
(defn A [b] (fn [a] (+ a b)))
(println ((A 3) 0))
(println (eval (list (A 3) 0)))
为什么?
调用(list (A 3))
返回列表中的函数:
user> (list (A 3) 0)
(#<user$A$fn__2934 user$A$fn__2934@2f09b4cb> 0)
eval
期望在列表中获得一个符号,并且它正在获得它自己的功能。如果您引用电话,(A 3)
那么您将获得您寻求的结果
user> (println (eval (list '(A 3) 0)))
3
nil
此代码的一部分在调用之前被评估eval
,然后eval
正在评估其余部分。更常见的是将 eval 用于带有术语的引用形式或选择性地不引用 ( ~
)。
user> (eval '((A 3) 0))
3
或者
user> (def my-number 3)
#'user/my-number
user> (eval `((A ~my-number) 0))
3
编辑:关于为什么它使用零参数而失败的问题:
如果您不将它们存储在 vars 中(即使用 defn 定义它们)而是手动内联它们,那么这两种形式似乎都可以工作:
user> (def A (fn [b] (fn [a] (+ a b))))
#'user/A
user> (eval (list (A 3) 0))
; Evaluation aborted.
user> (eval (list (fn [b] (fn [a] (+ a b)) 3) 0))
3