【问题标题】:Clojure's dot special form weirdnessClojure 的点特殊形式怪异
【发布时间】:2015-11-22 20:04:30
【问题描述】:

我很好奇为什么会这样(正如我在阅读 the documentation on the dot special form 后所期望的那样):

(map #(. % isInstance {}) [clojure.lang.IPersistentMap])

返回:

(true)

但这不是:

(. clojure.lang.IPersistentMap isInstance {})

我收到一个错误“没有匹配的方法:isInstance”。形式与上面的map 函数调用完全相同,但在map 之外,它不起作用。为什么?

【问题讨论】:

    标签: clojure clojure-java-interop


    【解决方案1】:

    .(点)螺旋形是其中最奇怪的。不知道我是否会很好地解释它,但让我们试试吧。

    docs:

    如果第一个操作数是解析为类名的符号,则访问被认为是对命名类的静态成员。请注意,根据 JVM 规范,嵌套类被命名为 EnclosureClass$NestedClass。 否则假定它是实例成员,并计算第一个参数以生成目标对象。

    强调我的。

    所以你已经遇到了(. clojure.lang.IPersistentMap isInstance {}) 的第一个案例 - clojure.lang.IPersistentMap 解析为类名,并且整个表达式被假定为静态方法调用。

    map 的情况下,符号被求值(强调的部分),在传递给匿名函数之前求值为clojure.lang.IPersistentMap 类对象,整个表达式是对该类的实例方法调用。

    所以归结为这样一个事实,在一个地方clojure.lang.IPersistentMap 被用作引用类名的符号,而在另一个地方被用作评估类对象的东西。

    也看here:

    请注意,类名通常表示类对象,但会以某些特殊形式进行特殊处理,例如'。和新的。

    【讨论】:

    • 这个解释是正确的,我只想补充一点,你可以强制编译器通过(. (do clojure.lang.IPersistentMap) isInstance {})(以及其他方式)来考虑类对象。然而. 特殊形式(和new 也是)非常低级,除非您正在编写一些互操作宏,否则您不应该使用它。优先使用.memberconstructor.Class/staticMember,而不是直接使用new.。如果您好奇,您应该了解这些糖化形式如何宏扩展为 .new 形式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-06
    • 2019-06-08
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    相关资源
    最近更新 更多