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 名称 [字段*] 选项 超类 超类参数 规格)"

与 clojure.core/deftype 类似,但可以扩展具体类,覆盖
并发调用在超类或其基类中定义的公共和受保护方法,以及访问/设置
这些类的公共和受保护字段。
超类参数是对超类构造函数的(可能为空的)参数向量

构造函数。
可以通过将参数 this 类型提示为超类来调用被覆盖的超类方法:(. ^SuperClass this 方法 参数 *)

例如:(defclass MyClass [name] {:extend java.util.List} java.util.AbstractList ["MyClass"] [name])
例如:(defclassroach MyBean [name] {:extend jbinit/IBean} iben) (extend Ents序列 [java.util.List])
`

例如:(extend-class 选项 超类 超类参数 规格)

类似于 clojure.core/reify,但可以扩展具体类,重写
并发调用在超类或其基类中定义的公共和受保护方法,以及访问/设置
这些类的公共和受保护字段。
超类参数是对超类构造函数的(可能为空的)参数向量

构造函数。
可以通过将参数 this 类型提示为超类来调用被覆盖的超类方法:(. ^SuperClass this 方法 参数 *)

例如:(defclass MyClass [name] {:extend java.util.List} java.util.AbstractList ["MyClass"] [name])
参数 this 作为超类:(. ^SuperClass this 方法 参数 *)

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

5 个回答

+1

评论者:bronsa

附上针对此功能的拟议实现

+1

评论者:bronsa

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

+1
参考:[https://clojure.atlassian.net/browse/CLJ-1255](https://clojure.atlassian.net/browse/CLJ-1255)(由mikera报告)
我正在编写可能会从中真正受益的代码。
我们对这个想法很感兴趣,但已经多次浏览了这个工单。但是,此补丁中修改编译器的做法比我们希望的更具侵入性。自上次交谈以来已有一段时间了,所以我对之后的细节记得不多。
0 投票

评论者:alexmiller

来自Rich:我们不希望在可移植构造(reify,deftype)中支持抽象类。然而,这将被视为Java专用的新构造(extend-class或reify-class)。如果您能适当修改工单,我们将将其移回已分配类别。

0 投票
...