请在 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 给出的 :tag 元数据时,它似乎具有一种有些奇怪的形式(因为它仍然是一系列调用,而不是类文字)

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

所以,:tag 看起来像是一个函数调用。编译器最终会调用 (class (log-window-proxy ...) 以获取可以真正用作类型提示的类吗?

否则,我会担心这个 :tag 元数据无效,这可能会导致反射警告,并且会使第三方工具产生困惑。

1 个答案

+1

选择
 
最佳答案

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

注释字符串对我来说暗示 t 应该是一个类(不是评估为类的东西)。它是否也适用于引用的案例是一个偶然事件 - 我不知道你是否应该期望它能够工作。你提出的这些问题进一步证明了这一点。"extend-type" 是"extend"的一个辅助包装程序,你可以直接使用 "extend"(一个函数)来获得评估后的类以及你想要的特定类型提示,如果在不寻常的这种情况下它们不同的话。
感谢你指出 `extend` 可以成为一个更好的选择。改进 Clojure 编译器以支持像我之前的评论中链接的两种用法(加上我的原始问题)可能会很有趣。

如果在未来可预见的时期内不会发生这种情况,我可能要改进 Eastwood 检查器,以便明确告知如何改进 extend-type/extend-protocol 的使用。
我认为这不是编译器问题,而是关于应该支持 `extend-type` 语法的问题。
by
目前是否有对该问题的明确答案?
by
我的理解是,extend-type 当前预期的是一个类,而不是评估为类的某个东西。
...