clojure实例?单参数
clojureclojure实例?单参数,clojure,instance,Clojure,Instance,clojure实例?函数让我有点困惑。似乎很乐意接受一个论点。所以 (instance? String) 工作正常,但总是返回false 我是不是遗漏了什么?我在两天内做了两次,两次调试都花费了我相当长的时间(是的,我同意,犯一次错误可能被视为不幸,但两次看起来像粗心大意) 为什么它没有中断,并出现算术错误 后面添加的注释: 从Clojure 1.6开始,此问题已修复 如果查看,您将看到调用的方法: (def ^{:arglists '([^Class c x]) :do
实例?
函数让我有点困惑。似乎很乐意接受一个论点。所以
(instance? String)
工作正常,但总是返回false
我是不是遗漏了什么?我在两天内做了两次,两次调试都花费了我相当长的时间(是的,我同意,犯一次错误可能被视为不幸,但两次看起来像粗心大意)
为什么它没有中断,并出现算术错误
后面添加的注释:
从Clojure 1.6开始,此问题已修复
如果查看,您将看到调用的方法:
(def
^{:arglists '([^Class c x])
:doc "Evaluates x and tests if it is an instance of the class
c. Returns true or false"
:added "1.0"}
instance? (fn instance? [^Class c x] (. c (isInstance x))))
看起来像在引擎盖下,当传递到
isInstance
时,被视为x
参数的默认值,并且返回false
我认为这是一个bug。如果您定义了instance?的新版本,例如
(def
^{:arglists '([^Class c x])
:doc "Evaluates x and tests if it is an instance of the class
c. Returns true or false"
:added "1.0"}
foo? (fn foo? [^Class c x] (. c (isInstance x))))
您将获得预期的异常
user=> (foo? String "bar")
true
user=> (foo? String 1)
false
user=> (foo? String)
ArityException Wrong number of args (1) passed to: user$foo-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
嗯……有趣。。。以下所有调用都失败(应该是这样的): 创建“instance?”函数对象的新实例的事件按预期工作:
user=> (def a (.newInstance (aget (.getConstructors (type instance?)) 0) (into-array [])))
#'user/a
user=> (a String)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (a String "")
true
有趣的。。。尽管
实例?
是在core.clj
中定义的,但对于(实例?
表单,clojure.lang.Compiler
似乎内置了特殊的处理
:
我认为这意味着,当编译/计算(实例?
表单时,core.clj
中定义的函数会被忽略,取而代之的是硬连接行为,它会将缺少的第二个参数解释为nil
。我猜这是出于性能原因,作为一种内衬
显然,这种特殊处理只适用于某些情况(我对编译器不够熟悉,不知道它们是什么)。正如Ankur的回答所示,调用
实例?
的方法会导致调用core.clj
中定义的函数。这一点本身无法解释观察到的行为,因为以这种方式定义的其他函数在使用不正确的参数数调用时会抛出arity异常。你是对的。我还没有用我自己版本的这个函数进行测试。我的错。看起来这个“问题”从Clojure 1.3开始就一直存在:有趣。我搜索了此线程建议的票证,但找不到。我猜它掉到电线下面了。我会看看我是否能想出如何提交一份新的bug报告。如果做不到这一点,我想我将包装实例?现在,您还可以调用实例?有两个以上的参数:(实例字符串“a”0)
->true
(实例字符串“a”0)
给出了ArityException错误当调用是直接调用且带有直接表示类的符号时,编译器中的快速路径(发出一个instanceof表达式)被采用。
user=> (def a (.newInstance (aget (.getConstructors (type instance?)) 0) (into-array [])))
#'user/a
user=> (a String)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (a String "")
true
if(fexpr instanceof VarExpr && ((VarExpr)fexpr).var.equals(INSTANCE))
{
if(RT.second(form) instanceof Symbol)
{
Class c = HostExpr.maybeClass(RT.second(form),false);
if(c != null)
return new InstanceOfExpr(c, analyze(context, RT.third(form)));
}
}