我对clojureinstance?
函数有点困惑。接受一个论点似乎很高兴。所以
(instance? String)
工作正常,但总是返回 false。
我在这里错过了什么吗?这两天我做了两次,两次都花了我相当长的时间来调试(是的,我同意,犯一次错误可能被认为是不幸,但两次看起来像粗心)。
为什么它不会因为arity错误而中断?
稍后添加的注释:从 Clojure 1.6 开始,此问题已得到修复!
我对clojureinstance?
函数有点困惑。接受一个论点似乎很高兴。所以
(instance? String)
工作正常,但总是返回 false。
我在这里错过了什么吗?这两天我做了两次,两次都花了我相当长的时间来调试(是的,我同意,犯一次错误可能被认为是不幸,但两次看起来像粗心)。
为什么它不会因为arity错误而中断?
稍后添加的注释:从 Clojure 1.6 开始,此问题已得到修复!
有趣......即使在instance?
中定义core.clj
,似乎也有内置的特殊处理clojure.lang.Compiler
形式(instance?)
。
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)));
}
}
我将其解释为,当您编译/评估(instance?)
表单时,core.clj
忽略中定义的函数以支持硬连线行为,该行为确实将缺少的第二个参数解释为nil
. 我猜这是出于性能原因,作为一种内联。
显然,这种特殊处理仅适用于某些情况(而且我对编译器不够熟悉,不知道它们是什么)。正如 Ankur 的回答所示,有一些调用方法instance?
会导致调用定义的函数core.clj
。
我认为这是一个错误。如果您定义一个新版本的实例?,例如
(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?
代码,您将看到调用isInstance
的方法:Class
(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))))
看起来像在幕后,nil
(或false
)x
在传递给时被视为参数的默认值,isInstance
并且返回false
。
嗯....有趣...以下所有调用都失败了(应该是这样的):
user=> (.invoke instance? String)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (instance? (type ""))
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (apply instance? String [])
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (#'instance? Long)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
创建“实例?”的新实例的事件 函数对象按预期工作:
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