Clojure具有gen-class,reify,proxy以及deftype和defrecord来定义新的类式数据类型。对于一种重视语法简单性并且讨厌不必要的复杂性的语言,这似乎是一种畸变。
有人可以解释为什么会这样吗?普通的Lisp风格的defclass是否足够?
最佳答案
这是三个不同因素的混合:
首先,让我们考虑一下这些功能。 deftype 和 gen-class 相似之处在于,它们都定义了用于提前编译的命名类。 Gen-class首先出现,其次是Clojure 1.2中的deftype。 Deftype是首选,并且具有更好的性能特征,但限制性更强。 deftype类可以符合接口(interface),但不能从另一个类继承。
验证和代理都用于在运行时动态创建匿名类的实例。 Proxy首先出现,Clojure 1.2中的deftype和defrecord伴随着reify。与deftype一样,在语义不太严格的情况下,最好使用Reify。
这就留下了一个问题,为什么deftype和defrecord会同时出现并起相似的作用。对于大多数目的,我们将要使用defrecord:它具有我们知道和喜爱的所有Clojure优点,可序列性等等。 Deftype旨在用作实现其他数据结构的低级构建块。它不包括常规的clojure接口(interface),但是它具有可变字段的选项(尽管这不是默认值)。
如需进一步阅读,请查看:
The clojure.org datatypes page
The google group thread where deftype and reify were introduced