请在2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以了解更多关于如何使用本站的信息。

+3
Java Interop

问题
- 各类Java API依赖于抽象基类的扩展而不是接口
- “proxy”存在限制(无法访问受保护的字段或超类)
- “proxy”因为额外的函数层和参数装箱等原因而带来性能开销
- “gen-class”复杂,并且与编译/字节码生成相关联

总之:Clojure目前没有好的/方便的方法来动态扩展Java抽象基类。

建议创建“reify”的一种变体,允许扩展单个抽象基类(可选地也扩展接口/协议)。代码生成将像直接在Java中扩展抽象基类一样发生(即,完全访问受保护的成员,以及完全类型提示的字段)。

由于这是一个仅适用于JVM的结构,它不应影响Clojure中的可移植扩展方法(deftype等)。我们建议将其放在一个单独的命名空间中,这可以作为其他JVM特定互操作功能的家园,例如“clojure.java.interop”。

建议的解决方案:所附补丁为该功能提出了一种实现方法,提供了一个新的clojure.interop命名空间,其中包含defclassextend-class宏。

`
"(defclass name [fields*] options 超类 super-args 规范)"

类似于clojure.core/deftype但可以扩展具体类、重写并调用在超类或其基类中定义的公共和保护方法;访问/设置那些的公共和保护字段。
super-args是一个(可能为空的)构造函数的参数向量
通过类型提示参数作为超类,可以在重写超方法的同时调用它:(. ^SuperClass this method args*)"




`

`"(extend-class options 超类 super-args 规范)`

类似于clojure.core/reify但可以扩展具体类:重写并调用作为超类参数:(. ^SuperClass this method args*)"`
super-args是一个(可能为空的)构造函数的参数向量
通过类型提示参数作为超类,可以在重写超方法的同时调用它:(. ^SuperClass this method args*)"



补丁: 0001-CLJ-1225-add-defclass-extend-class-v2.patch

请求: jira

5 个答案

+1

评论者:bronsa

附上此功能的建议实现

+1

评论者:bronsa

更新的补丁与v1相同,但在master的基础上刷新

+1
参考: https://clojure.atlassian.net/browse/CLJ-1255(由mikera报告)
我正在编写可以从这项功能真正受益的代码。
我们对此想法感兴趣,已经多次浏览这个工单,但这个补丁中修改编译器的方法比我们想要的更具侵略性。自从我上次讨论这个问题以来已经有一段时间了,所以我不记得很多细节。
0

评论者:alexmiller

Rich的意见:我们不希望支持抽象类在可移植的结构中(reify,deftype)。然而,这将被视为一个新的Java-only结构(extend-class或reify-class)。如果您能相应地修改工单,将会将其恢复到已分类状态。

0

评论者:bronsa

更多关于提议实现的文档可以在https://docs.google.com/document/d/1OcewjSpxmeFRQ3TizcaRRwlV34T8wl4wVED138FHFFE找到,non squashed commits可以在https://github.com/clojure/clojure/compare/master...Bronsa:defclass找到

...