在Clojure中创建Java类有几种不同的方法,那么在Clojure中在gen-class
,proxy
和reify
之间进行选择时有什么权衡? (还有其他方法可以创建我没有列出的Java类吗?)
我的基本理解是我已经按照权力的递减顺序列出了这些结构。
答案 0 :(得分:18)
如果需要命名类,或者要为要创建的对象添加新方法,请使用gen-class
。 gen-class
依赖于AOT编译。
如果您想要使用reify
或proxy
进行匿名,一次性的类型实施。他们不依赖于AOT编译。以下是他们的不同之处:
reify
仅支持协议或接口,proxy
也支持具体的超类。 reify
使用真正的类方法,proxy
使用外部函数。reify
使用直接方法查找,而proxy
使用地图进行方法查找。reify
不支持动态交换方法,但proxy
会这样做。 reify
的效果优于proxy
,因此您应该尽可能使用reify
。仅在proxy
的约束过于严格时才使用reify
。
答案 1 :(得分:10)
除了gen-class,proxy和reify之外,我们还有defrecord和deftype。后两个选项应该是创建命名java类的第一选择(在defrecord的情况下,对于任何具有命名组件的结构的首选。)
datatypes page on clojure.org是这个主题的一个很好的参考。 Defrecord,deftype和reify比gen-class和proxy更新,已经在版本1.2中引入(我认为 - 可能是1.1)。 Defrecord和deftype都创建符合接口的类,但不允许继承。如果你需要继承,gen-class(和匿名类的代理)仍然是你唯一的选择。
Defrecord和deftype在免费赠送的内容上有所不同。 Defrecord自动创建一个符合IPersistentMap和ISeq的类。另一方面,Deftype可以让您更好地控制您的类,甚至允许可变字段(在defrecord中不允许)。通常,deftype用于数据结构的低级实现,而defrecord用于大多数日常使用。