请分享您的看法参加2024年Clojure状况调查!

欢迎!请参阅关于页面以了解更多关于其工作方式的信息。

+3投票
Java Interop

问题
- 不同的Java API依赖于扩展抽象基类而非接口
- "proxy"有局限性(不能访问受保护的字段或super)
- "proxy"因为有一个额外的函数层/参数装箱等问题,有性能开销。
- "gen-class"复杂,与编译/字节码生成有冲突。

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

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

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

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

`
“(defclass 名称 [字段*] 选项 父类 父类参数 规格)”

像clojure.core/deftype一样,但可以扩展一个具体类,覆盖
和调用父类或
其基类中定义的公共和受保护方法,并访问/设置受保护的字段。
超参数是一个(可能为空的)向量,包含传递给父类构造函数的参数。

super-args是一个传递给父类构造函数的参数向量
构造函数

可以通过将参数this类型提示为父类,在覆盖的同时调用超方法:
(. ^SuperClass this 方法 参数*)”
`

```(extend-class 选项 父类 父类参数 规格)```

像clojure.core/reify一样,但可以扩展一个具体类,覆盖参数
和调用父类或
其基类中定义的公共和受保护方法,并访问/设置受保护的字段。
超参数是一个(可能为空的)向量,包含传递给父类构造函数的参数。

super-args是一个传递给父类构造函数的参数向量
构造函数

可以通过将参数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 (由mikera报告)
我也正在编写可以从这一点中受益的代码。
我们对此想法感兴趣,并且已经多次浏览了这个工单,但这里补丁中修改编译器的方法比我们希望的更具侵略性。自从我进行过这次对话以来已经有一段时间了,因此我对除了那之外的大部分细节都不太记得了。
0 投票

评论由:alexmiller

来自Rich的消息:我们不想在可移植结构(reify、deftype)中支持抽象类。然而,这将被视为一个新的仅Java的构造(extend-class或reify-class)。如果你能相应地修改工单,我们将将其移回已分派的状态。

0 投票
...