动态让Clojure? [英] Dynamic let in Clojure?

查看:115
本文介绍了动态让Clojure?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在REPL中发生以下情况:

  mathematics.core> (let [zebra 1](resolve'zebra))
nil
mathematics.core> (def zebra 1)
#'mathematics.core / zebra
mathematics.core> (let [zebra 2](when(resolve'zebra)(eval'zebra)))
1


$ b b

基本上,我想使用类似于 let 的形式动态地绑定值到变量,并且具有该形式内的函数能够访问该变量的值绑定到。

  mathematics.core> (def ^:dynamic zebra 1)
#'mathematics.core / zebra
mathematics.core> (绑定[zebra 2](when(resolve'zebra)(eval'zebra)))
2


$ b b

绑定似乎做了我想要的技巧,但AFAIK它需要一个变量定义与:dynamic 元数据。我想能够使用以前从未被定义过的变量,并且表单中的表达式能够访问该变量,就好像它被实际定义一样。



要说明,我想要这样的:

  mathematics.core> (let-dynamic [undefined-variable 1] 
(when(resolve'undefined-variable)(eval'unresolved-variable)))
1
pre>

有一个简单的方法吗?

解决方案

这不会工作得特别好。如果没有定义符号,那么Clojure编译器不能编译任何使用它的代码。你可能可以得到某种类型的黑客使用宏,调用def懒惰的需要时,但它会是一些很讨厌的代码.....



建议只使用绑定,并提前定义您的vars。你应该能够以这种方式工作的方式编写代码。



我认为定义变量是一个坏主意。我不认为你应该真的需要这个 - 如果你在代码中使用的变量,肯定很容易做一个(def ^:dynamic ...)预先为您使用的每个变量?


I have the following happening in the REPL:

mathematics.core> (let [zebra 1] (resolve 'zebra))
nil
mathematics.core> (def zebra 1)
#'mathematics.core/zebra
mathematics.core> (let [zebra 2] (when (resolve 'zebra) (eval 'zebra))) 
1

Basically, I would like to dynamically bind values to variables using something like a let form, and have functions inside that form be able to access the value the variable is bound to.

mathematics.core> (def ^:dynamic zebra 1)
#'mathematics.core/zebra   
mathematics.core> (binding [zebra 2] (when (resolve 'zebra) (eval 'zebra))) 
2

binding seems to do the trick I want, but AFAIK it requires a variable to be defined with the :dynamic metadata first. I want to be able to use variables that have never been defined before on the fly, and have expressions in the form be able to access that variable as if it were actually defined.

To illustrate, I want something like this:

mathematics.core> (let-dynamic [undefined-variable 1]
                    (when (resolve 'undefined-variable) (eval 'unresolved-variable)))
1

Is there an easy way to do this? Or a way to accomplish this using macros?

解决方案

This isn't going to work particularly well. If the symbol isn't defined, then the Clojure compiler can't compile any code that uses it. You might be able to get some kind of hack working with macros that call def lazily when needed, but it would be some pretty nasty code.....

I would suggest just using binding, and define your vars in advance. You should be able to write your code in the way that this works.

I think it's a bad idea to define variables "on the fly". I don't think you should ever really need this - if you are using the variable in the code, surely it is easy enough just to do a (def ^:dynamic ...) beforehand for each variable that you use?

这篇关于动态让Clojure?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆