首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Clojure中的变量作用域+ eval

Clojure中的变量作用域+ eval
EN

Stack Overflow用户
提问于 2011-06-03 08:05:03
回答 1查看 3.2K关注 0票数 19

在Clojure中,

代码语言:javascript
复制
(def x 3)
(eval '(prn x))

打印3,而

代码语言:javascript
复制
(let [y 3]
   (eval '(prn y)))

代码语言:javascript
复制
(binding [z 3] (eval '(prn z)))

生成“Unable to resolve var”异常。

根据http://clojure.org/evaluationevalload-string等生成临时名称空间来评估它们的内容。因此,由于(def x 3)是在我当前的名称空间中完成的,而不是在eval创建的名称空间中完成的,因此我认为上面的代码示例都不起作用。

  1. 为什么在不使用def

的情况下,第一个代码示例可以工作,而后两个代码不能?

  • 如何才能对具有绑定变量的窗体执行eval操作

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-03 08:22:37

1.:

这不起作用的原因是(或多或少)在你链接的页面上给出的:

代码语言:javascript
复制
It is an error if there is no global var named by the symbol […]

和:

  1. 在当前名称空间中执行查找,以查看是否存在从符号到var的映射。如果是,则该值是符号引用的var的绑定值。
  2. 这是一个错误。

eval在一个空的(CL-lingo中的null)词法环境中计算表单。这意味着,您不能从调用者的作用域访问词法变量绑定。此外,binding为现有的var创建新的绑定,这就是为什么在没有declared或defed您试图绑定的变量的情况下不能“单独”使用它的原因。此外,词法变量(至少在CL中,但如果Clojure不是这种情况,我会感到惊讶)在运行时已经不存在了-它们被转换为地址或值。

另请参阅关于此主题的my older post

2.:

所以,你必须使用动态变量。您可以避免显式的def,但至少仍然需要对它们进行绑定(def的var在没有绑定的情况下对它们进行命名):

代码语言:javascript
复制
user=> (declare ^:dynamic x)
#'user/x
user=> (binding [x 10] (eval '(prn x)))
10
nil

顺便说一句:我想你知道为什么需要eval,当其他解决方案合适的时候,它的用法是considered evil

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6221716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档