我在clojure中定义了以下内容:
(def ax '(fn x [] (+ 1 z)))
(let [z 4]
(str (eval ax))
)
Run Code Online (Sandbox Code Playgroud)
:但不是返回:
5
Run Code Online (Sandbox Code Playgroud)
:我得到:
Unable to resolve symbol: z in this context
Run Code Online (Sandbox Code Playgroud)
:我已经尝试将"let"更改为"绑定"但这仍然无效.有人知道这里有什么问题吗?
Iai*_*ain 11
对代码进行尽可能小的更改以使其工作:
(def ^:dynamic z nil)
(def ax '(fn x [] (+ 1 z)))
(binding [z 4]
(str ((eval ax)))
)
Run Code Online (Sandbox Code Playgroud)
这两个变化是将z定义为动态变量,以便名称解析,并放置另一个paren(eval ax),因为ax正在返回一个函数.
更好一点是改变ax的定义:
(def ^:dynamic z nil)
(def ax '(+ 1 z))
(binding [z 4]
(str (eval ax))
)
Run Code Online (Sandbox Code Playgroud)
因此,评估ax会立即获得您想要的结果,而不是返回执行此操作的函数.
再好的是跳过eval:
(def ^:dynamic z nil)
(defn ax [] (+ 1 z))
(binding [z 5]
(str (ax))
)
Run Code Online (Sandbox Code Playgroud)
但最重要的是不要将z作为var浮动,并将其传递给ax,如Mimsbrunnr和Joost建议的那样.
简短的回答是不要使用eval.你几乎不需要,当然也不需要.
例如:
user> (defn ax [z]
(+ 1 z))
#'user/ax
user> (let [f #(ax 4)]
(f))
5
Run Code Online (Sandbox Code Playgroud)