clojure实例?单一论点

时间:2012-11-01 11:47:36

标签: clojure instance

我对clojure instance?函数感到有些困惑。采取一个论点似乎很高兴。所以

(instance? String) 

工作正常,但总是返回false。

我在这里遗漏了什么吗?我在两天内完成了两次,两次都花了我相当长的时间来调试(是的,我同意,犯错误一次可能被视为不幸,但两次看起来像粗心)。

为什么不打破,出现arity错误?

注意后来添加: 截至Clojure 1.6,这已得到修复!

http://dev.clojure.org/jira/browse/CLJ-1171

4 个答案:

答案 0 :(得分:8)

有趣......即使在instance?中定义了core.clj,似乎clojure.lang.Compiler形式的(instance?)内置了特殊处理。

Compiler.java, line 3498

    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中定义的函数。

答案 1 :(得分:3)

我认为这是一个错误。如果定义实例的新版本?,例如

(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)

答案 2 :(得分:2)

如果查看instance? code,您会看到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 (or false)被视为传递给x并返回isInstance的{​​{1}}参数的默认值。

答案 3 :(得分:2)

嗯......有趣......以下所有调用都失败了(这应该是怎么回事):

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