【问题标题】:eval a list into a let on clojure将列表评估为 clojure 上的 let
【发布时间】:2012-01-29 13:18:22
【问题描述】:

我的问题是下一个,我尝试使用 let 为这个 vars 分配值来评估一个包含一些 vars 的列表

如果我这样做 (def a (list * 'x 'y))(let [x 3 y 3] (eval a)) 我有一个 CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compile:(NO_SOURCE_PATH:6)

但是如果我跑 (def x 4) (def y 4)(eval a) 我有 16 个,无论如何如果我再次运行(let [x 3 y 3] (eval a)) 我有 16 个,

是否存在正确绑定 x 和 y 并评估列表的方法?

ty!

【问题讨论】:

    标签: binding clojure eval let


    【解决方案1】:

    嗯,你也可以evallet 表达式,看看这是不是你需要的:

    (eval '(let [x 3 y 3] (* x y)))
    

    编辑:

    根据 cmets,这将适用于您的情况:

    (def a (list (list * 'x 'y)))
    (eval (concat '(let [x 3 y 3]) a))
    

    更好的是,使用准引用:

    (def a (list * 'x 'y))
    (eval `(let ~'[x 3 y 3] ~a))
    

    【讨论】:

      【解决方案2】:
      (def ^:dynamic x 4) (def ^:dynamic y 4)
      user=> (binding [x 3 y 3] (eval a))
      9
      user=> (eval a)
      16
      

      【讨论】:

        【解决方案3】:

        let 定义了无法从 eval 函数体访问的词法范围绑定。这与任何其他功能没有什么不同。但是,使用def 创建的绑定是可访问的,因为它们是全局命名空间。所有函数都可以访问命名空间全局变量,只要它们是公共的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          • 2012-11-19
          • 1970-01-01
          • 2012-03-13
          • 2010-12-25
          • 1970-01-01
          • 2010-10-13
          相关资源
          最近更新 更多