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 linter,以便清楚地告知如何改进extend-type/extend-protocol的使用。
我认为这不是编译器问题,而是关于`extend-type`要支持的语法问题。
目前对那个问题有明确的答案吗?
我认为extend-type目前期望的是类,而不是评估为类的东西。
...