在Clojure中,似乎有多种实现数据模型的方式:
- 普通内置数据类型(maps/lists/sets/vectors)
- 内置数据类型+元数据--例如:
(type ^{:type ::mytype} {:fieldname 1})
- 内置数据类型+特殊访问器函数(例如,从地图中获取不存在的键会抛出异常,而不是静默返回
nil
) - deftype
- defstruct
- defrecord
- defprotocol
我们已经到了地图/列表不再适用于我们的地步——我们遇到了大量错误,预先条件/后置条件很容易捕获,但是如果不这样做,追踪起来需要很长时间(并且难以编写接受嵌套地图/列表/向量的函数的有效前/post-conditions)——但我们不确定该选择上述哪一个。
我们有三个主要目标:
- 编写惯用的Clojure代码
- 避免花费大量时间寻找愚蠢的类型错误
- 对于我们能够更改/重构代码而不会破坏任何东西,有信心
我们如何利用Clojure的力量来帮助我们?
defrecord
和defprotocol
,可以忽略defstruct
,也不必过于担心deftype
。在Clojure程序中,defrecord
创建Java代码是否重要--我的意思是,我不想担心有一个Java类,但如果Clojure想私下使用一个,那就没问题了?非常好的答案,非常有帮助。 - Matt Fenwick根据给定名称为类动态生成已编译字节码,在与当前命名空间同名的包中,包括给定字段和可选的协议和/或接口方法。
(来自defrecord文档) - Matt Fenwick