gpt4 book ai didi

binding - Clojure 中的变量作用域 + eval

转载 作者:行者123 更新时间:2023-12-03 13:34:23 26 4
gpt4 key购买 nike

在 Clojure 中,

(def x 3)
(eval '(prn x))

打印 3,而
(let [y 3]
(eval '(prn y)))


(binding [z 3] (eval '(prn z)))

生成“无法解析 var”异常。

根据 http://clojure.org/evaluation , eval , load-string等生成临时命名空间来评估它们的内容。因此,我希望上述代码示例都不起作用,因为 (def x 3)在我当前的命名空间中完成,而不是由 eval 创建的命名空间.
  • 为什么第一个代码示例有效,而后两个无效?
  • 我怎么能eval不使用 def 的带有绑定(bind)变量的表单?

  • 谢谢!

    最佳答案

    1.:

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

    It is an error if there is no global var named by the symbol […]

    和:

    […]

    1. A lookup is done in the current namespace to see if there is a mapping from the symbol to a var. If so, the value is the value of the binding of the var referred-to by the symbol.

    2. It is an error.


    eval在空的( null 在 CL 语言中)词法环境中计算表单。这意味着,您不能从调用者的范围内访问词法变量绑定(bind)。另外, binding为现有变量创建新的绑定(bind),这就是为什么你不能“单独”使用它,而没有 declare d 或 def编辑您尝试绑定(bind)的变量。此外,词法变量(至少在 CL 中,但如果 Clojure 不是这种情况,我会感到惊讶)在运行时已经不复存在——它们被转换为地址或值。

    另见我的 older post关于这个话题。

    2.:

    所以,你必须使用动态变量。您可以避免显式 def ,但你至少还需要 declare它们(其中 def 的 var 名称没有绑定(bind)):
    user=> (declare ^:dynamic x)
    #'user/x
    user=> (binding [x 10] (eval '(prn x)))
    10
    nil

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

    关于binding - Clojure 中的变量作用域 + eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6221716/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com