2024 Clojure 状况调查中分享您的想法!

欢迎!请查看关于页面以获取更多关于如何使用本站的信息。

0
编译器

以下是一个有效的Clojure示例(关注extend-type (class (log-window-proxy nil)),而不是引用类字面量)

(defn- log-window-proxy [state]
  (proxy [javax.swing.JTextArea clojure.lang.IDeref] []
    (deref [] state)
    (scrollRectToVisible [rect]
      (if @(:auto-scroll? state)
        (proxy-super scrollRectToVisible rect)))))

(defprotocol LogWindow
  (log   [this message])
  (clear [this]))

(extend-type (class (log-window-proxy nil))
  LogWindow
  (log [this message]
    (println "message" message))
  (clear [this]
    nil))

然而,当检查this被提供的:标签元数据时,它看起来有一个相当奇怪的形式(因为它仍然是调用链,而不是类字面量)

(-> (extend-type (class (log-window-proxy nil))
      LogWindow
      (log [this message]
        (println "message" message))
      (clear [this]
        nil)) quote macroexpand last :log second ffirst meta)
;; => {:tag (class (log-window-proxy nil))}

所以,:标签看起来像是一个函数调用。编译器会不会最终调用(class (log-window-proxy ...以获取它实际上可用的类型提示类?

否则,我会担心这个:标签元数据是无效的,这可能会导致反射警告,并可能混淆第三方工具。

1 答案

+1

被选中
 
最佳答案

为什么你说这是有效的Clojure?

文档字符串暗示我`t`应该是类(而不是评估为类的某种东西)。但这并不意味着在引用的案例中也会工作,我不知道是否应该期望这能工作。你提出的问题就是为此提供了进一步的证据。"extend-type"是围绕"extend"的辅助包装器,直接使用"extend"(一个函数)可以得到评估后的类以及你需要的特定类型提示,如果在这特殊情况下有所不同的话。
感谢指出 `extend` 可以是一个更好的选择。也许将 Clojure 编译器改进以支持前一个评论中链接的两个用法(加上我的原始帖子)会很有趣。

如果在未来可预见的将来不会这样做,我可能会对 Eastwood 检查器进行优化,以便清楚地通知如何改进 extend-type/extend-protocol 的使用。
我认为这不是编译器问题,而是一个关于`extend-type`支持的语法的问题。
目前是否有对这个问题的明确答案?
我认为extend-type目前期望的是一个类,而不是evals到一个类的内容。
...