- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我这样做:
(eval (let [f (fn [& _] 10)]
`(~f nil)))
它按预期返回 10。
虽然如果我这样做:
(eval (let [f (constantly 10)]
`(~f nil)))
它抛出一个异常:
IllegalArgumentException No matching ctor found for
class clojure.core$constantly$fn__... clojure.lang.Reflector.invokeConstructor
既然两者是等价的,为什么代码总是不起作用?
最佳答案
这个问题有两个答案,要真正明白。
首先,澄清为什么你的 eval
在第二种情况下,表单没有给你预期的结果,请注意 f
已被分配等于函数 (fn [& _] 10)
.这意味着当评估该表单时,将再次评估函数对象——可能不是您想要的。
tl;博士:f
当它被绑定(bind)时被评估,当你创建的表单是 eval
时再次被评估(结果不明确) 'd.
一个(匿名函数)有效而另一个失败的原因意味着我们必须查看评估过程的一些内部结构。
当 Clojure 计算对象表达式(如由函数对象形成的表达式)时,它使用以下方法,在 clojure.lang.Compiler$ObjExpr
中
public Object eval() {
if(isDeftype())
return null;
try
{
return getCompiledClass().newInstance();
}
catch(Exception e)
{
throw Util.sneakyThrow(e);
}
}
在 REPL 试试这个:
从一个匿名函数开始:
user=> (fn [& _] 10)
#<user$eval141$fn__142 user$eval141$fn__142@2b2a5dd1>
user=> (.getClass *1)
user$eval141$fn__142
user=> (.newInstance *1)
#<user$eval141$fn__142 user$eval141$fn__142@ee7a10e> ; different instance
user=> (*1)
10
请注意 newInstance
在 Class
调用该类的空构造函数——一个不带参数的构造函数。
现在尝试关闭某些值的函数
user=> (let [x 10] #(+ x 1))
#<user$eval151$fn__152 user$eval151$fn__152@3a565388>
user=> (.getClass *1)
user$eval151$fn__152
user=> (.newInstance *1)
InstantiationException user$eval151$fn__152 [...]
由于闭包的上值是在构造时设置的,这种函数类没有空构造函数,并且创建一个没有上下文的新函数类失败。
最后看constantly
的出处
user=> (source constantly)
(defn constantly
"Returns a function that takes any number of arguments and returns x."
{:added "1.0"
:static true}
[x] (fn [& args] x))
constantly
返回的函数关闭x
所以编译器将无法 eval
这种功能。
tl;dr(再次):可以用这种方式计算没有上值的函数,并生成相同函数的新实例。不能像这样评估具有上值的函数。
关于clojure - 不断地发挥作用在语法引用中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23573512/
在 Play 1.x 中有很棒的 play Idealize(和 play eclipsify),它为您最喜欢的 IDE 中的 Play 项目准备了项目文件。 我看到这是在 Play 2.X 中删除的
我是一名优秀的程序员,十分优秀!