Clojure:我如何绑定变量?

时间:2011-03-26 10:40:12

标签: clojure

我在clojure中定义了以下内容:

(def ax '(fn x [] (+ 1 z)))

(let [z 4]
    (str (eval ax))
)

:但不是返回:

5

:我明白了:

Unable to resolve symbol: z in this context 

:我尝试将“let”更改为“绑定”但这仍然无效。有人知道这里有什么问题吗?

3 个答案:

答案 0 :(得分:11)

对代码进行尽可能小的更改以使其正常工作:

(def ^:dynamic z nil)

(def ax '(fn x [] (+ 1 z)))

(binding [z 4]
    (str ((eval ax)))
)

这两个变化是将z定义为动态变量,以便名称解析,并放置另一个paren(eval ax),因为ax正在返回一个函数。

更好一点是改变ax的定义:

(def ^:dynamic z nil)

(def ax '(+ 1 z))

(binding [z 4]
    (str (eval ax))
)

因此,评估ax会立即获得您想要的结果,而不是返回执行此操作的函数。

再次尼尔是跳过评估:

(def ^:dynamic z nil)

(defn ax [] (+ 1 z))

(binding [z 5]
    (str (ax))
)

但最重要的是不要让z作为var浮动,并将其传递给ax,就像Mimsbrunnr和Joost建议的那样。

答案 1 :(得分:8)

简短的回答是不要使用eval。你几乎不需要,当然也不需要。

例如:

user> (defn ax [z]
         (+ 1 z))
#'user/ax
user> (let [f #(ax 4)]
         (f))
5

答案 2 :(得分:1)

是的,所以我不完全确定你在这里要做什么。

我的意思是这个有用,虽然它没有使用eval,它将x定义为函数(fn [ x ] (+ x 1))

> (def x #(+ 1 %))
#'sandbox102711/x
> (x 4)
5

最后,eval不是你应该使用的东西。正如Lisp Cljoure对lambda抽象和宏的支持(参见上面的fn定义)应该不再需要。