请在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应该是一个类(不是.eval()到类的某种东西)。它是否也适用于引用的案例是附带说明的——我不知道你应该期望它这样做。你提出的问题进一步证明了这一点。extend-type是围绕extend的助手包装器,如果在这个特殊情况下它们不同,你可以直接使用extend(一个函数)来获取评估后的类以及你寻求的特定类型提示。
感谢指出`extend`可以是一个更好的选择。改进Clojure编译器以支持我之前评论中链接的两个使用情况(以及我的OP)可能会很有趣。

如果这在可预见的未来不会发生,我可能会改进Eastwood linter来清楚地告知如何改进extend-type/extend-protocol的使用。
我认为这不是编译器的问题,而是关于`extend-type`支持何种语法的疑问。
by
目前对那个问题有确定的答案吗?
by
我的理解是,目前extend-type函数期望一个类,而不是求值为一个类的某物。
...