简体   繁体   English

Clojure:我如何绑定变量?

[英]Clojure: How can I bind a variable?

I have the following defined in clojure: 我在clojure中定义了以下内容:

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

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

:but instead of returning : :但不是返回:

5

: I get : :我得到:

Unable to resolve symbol: z in this context 

: I have tried changing "let" to "binding" but this still does not work. :我已经尝试将“let”更改为“绑定”但这仍然无效。 Does anyone know what is wrong here? 有人知道这里有什么问题吗?

Making the smallest possible changes to your code to get it to work: 对代码进行尽可能小的更改以使其工作:

(def ^:dynamic z nil)

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

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

The two changes are defining z as a dynamic var, so that the name resolves, and putting another paren around (eval ax), because ax is returning a function. 这两个变化是将z定义为动态变量,以便名称解析,并放置另一个paren(eval ax),因为ax正在返回一个函数。

A little bit nicer is to change the definition of ax: 更好一点是改变ax的定义:

(def ^:dynamic z nil)

(def ax '(+ 1 z))

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

So evaluating ax immediately gets the result you want, rather than returning a function that does it. 因此,评估ax会立即获得您想要的结果,而不是返回执行此操作的函数。

Nicer again is to skip the eval: 再好的是跳过eval:

(def ^:dynamic z nil)

(defn ax [] (+ 1 z))

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

But best of all is to not have z floating around as a var, and pass it in to ax as Mimsbrunnr and Joost suggested. 但最重要的是不要将z作为var浮动,并将其传递给ax,如Mimsbrunnr和Joost建议的那样。

The short answer is don't use eval. 简短的回答是不要使用eval。 You almost never need to, and certainly not here. 你几乎不需要,当然也不需要。

For example: 例如:

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

Right so I'm not entirely sure what you are trying to do here. 是的,所以我不完全确定你在这里要做什么。

I mean this works, though it's not using eval it's defining x to be the function (fn [ x ] (+ x 1)) 我的意思是这个有效,虽然它没有使用eval它将x定义为函数(fn [ x ] (+ x 1))

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

In the end, eval is not something you should be using. 最后,eval不是你应该使用的东西。 As a Lisp Cljoure's support for lambda abstraction and macros ( see the fn definition above ) should remove the need. 正如Lisp Cljoure对lambda抽象和宏的支持(参见上面的fn定义)应该消除了需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM