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

欢迎!请参阅关于页面了解有关该如何工作的更多信息。

0
编译器

以下是一个有效的Clojure示例( focus on 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`要支持哪种语法的问题。
by
目前有关于这个问题的确定答案吗?
by
我的理解是,extend-type 当前期望一个类,而不是一个可以eval为类的对象。
...