2024 Clojure状态调查中分享你的想法!

欢迎!请参阅关于页面以获取更多关于如何使用的详情。

+3
Java互操作

问题
- 各种Java API依赖于扩展抽象基类而不是接口
- "proxy" 有限制(无法访问受保护的字段或super)
- "proxy"由于额外的功能层(如函数/参数装箱等)而具有性能开销
- "gen-class" 复杂且与编译/字节码生成相关联

总结:Clojure目前没有一种很好的/便捷的方式来动态地扩展Java抽象基类。

建议创建一个 "reify" 变种,允许扩展单个抽象基类(可选地还包括接口/协议)。代码生成会在仿佛抽象基类已经在Java中直接扩展的情况下发生(即,具有完全访问受保护的成员以及完全类型提示的字段)。

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

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

`
``(defclass name [fields*] options super-class super-args specs)

类似于 clojure.core/deftype,但是可以扩展具体的类,重写
并调用在超类或其基类中定义的公共和受保护方法,以及访问/设置这些的公共和受保护字段

super-args 是传递给超类构造函数的(可能是空的)向量参数


可以通过将参数 this 类型提示为超类来调用覆盖的方法,例如:(. ^SuperClass this method args*)"
``
`

``(extend-class options super-class super-args specs)

类似于 clojure.core/reify,但是可以扩展具体的类,重写
并调用在超类或其基类中定义的公共和受保护方法,以及访问/设置这些的公共和受保护字段

super-args 是传递给超类构造函数的(可能是空的)向量参数


可以通过将参数 this 类型提示为超类来调用覆盖的方法,例如:(. ^SuperClass this method args*)"
可以通过将参数 this 类型提示为超类来调用覆盖的方法,例如:(. ^SuperClass this method args*)"

``

登录注册来添加评论。

登录注册来回答此问题。

评论由:bronsa 提供

附上该功能的提议实现

登录注册来回答此问题。

评论由:bronsa 提供

更新的补丁与v1相同,但在master分支上刷新

登录注册来回答此问题。
参考: https://clojure.atlassian.net/browse/CLJ-1255(由 mikera 提出)
我正在编写可以从这一点真正受益的代码。
我们对这个想法很感兴趣,并且已经多次浏览了此票证,但这里补丁中修改编译器的方法比我们想要的更加激进。自从我有这个对话以来已经有一段时间了,所以我记不起那个细节之外的事情。
0

评论由:alexmiller 提供

Rich 说:我们不想在可移植结构(reify,deftype)中支持抽象类。不过,这将被考虑为一个只支持 Java 的新构造(extend-class 或 reify-class)。如果你能相应地修改这个票证,就可以将其移回 Triaged。

0

评论由:bronsa 提供

更多有关建议实现的文档可以在 https://docs.google.com/document/d/1OcewjSpxmeFRQ3TizcaRRwlV34T8wl4wVED138FHFFE 找到,未压缩的提交在 https://github.com/clojure/clojure/compare/master...Bronsa:defclass

...