作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个这样定义的函数规范,我想将它评估为一个函数对象,以便我可以传递。
(def spec '(foo [n] (* 2 n)))
(defmacro evspec [name arg & body] `(defn ~name [~arg] ~@body))
(evspec foo n (* 2 n))
(let [foo (first spec) arg (first (second spec)) body (last spec)]
(evspec foo arg body))
user=> (foo 3)
(* 2 n)
user=> foo
#<user$eval766$foo__767 user$eval766$foo__767@39263b07>
user=> foo
#<user$foo user$foo@66cf7fda>
最佳答案
如果没有 eval
,一般情况下根本不可能做到这一点。 .宏只是一个函数,它在编译时按字面意思传递其参数表达式(通常根本不可能知道它们在运行时的值可能是什么)。特别是在对 evspec
的调用中里面let
问题文本中的形式,其中返回值为(* 2 n)
, evspec
宏扩展器从字面上看到符号 foo
和符号 n
作为它的位置参数和(body)
(包含单个符号 body
的序列)作为其“rest”参数;返回值与这些输入一致。
但是,使用 eval
出于这种目的是完全可以的。重要的是要记住它有相当大的运行时成本,所以你会想稍微谨慎地使用它,但是一旦你使用 eval
生成一个函数,它是一个非常好的 Clojure 函数,和其他任何函数一样快。
另外,请注意,在 JavaScript 中 eval
对文本进行操作,Clojure 的 eval
对 Clojure 数据结构进行操作——实际上与宏操作的数据结构相同——这可以说使其更不容易出错。
关于clojure - 如何将列表形式转换为clojure中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17560627/
我是一名优秀的程序员,十分优秀!