【发布时间】:2011-08-15 10:51:26
【问题描述】:
有几种不同的方法可以在 Clojure 中创建 Java 类,那么在 Clojure 中的 gen-class、proxy 和 reify 之间进行选择时有哪些权衡? (还有其他方法可以创建我没有列出的 Java 类吗?)
我的基本理解是,我按功率降序列出了这些构造。
【问题讨论】:
标签: clojure clojure-java-interop
有几种不同的方法可以在 Clojure 中创建 Java 类,那么在 Clojure 中的 gen-class、proxy 和 reify 之间进行选择时有哪些权衡? (还有其他方法可以创建我没有列出的 Java 类吗?)
我的基本理解是,我按功率降序列出了这些构造。
【问题讨论】:
标签: clojure clojure-java-interop
当你想要一个命名类或者你想为你创建的对象添加新方法时使用gen-class。 gen-class 依赖 AOT 编译。
当您想要一种匿名的一次性实现时,您可以使用reify 或proxy。它们不依赖 AOT 编译。以下是它们的区别:
reify 只支持协议或接口,proxy 也支持具体的超类。 reify 使用真正的类方法,proxy 使用外部函数。reify 使用直接方法查找,而proxy 使用映射进行方法查找。reify 不支持方法的动态交换,但proxy 支持。reify 的性能会比proxy 好,因此您应该尽可能使用reify。仅当reify 的约束过于严格时才使用proxy。
【讨论】:
除了 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 用于大多数日常使用。
【讨论】: