我正在 Clojure 中开发具有多个子结构的复杂数据结构。
我知道随着时间的推移我会想要扩展这个结构,并且有时可能想要在不破坏数据结构的不同用户的情况下改变内部结构(例如,我可能想要将向量更改为哈希图,添加某种索引出于性能原因的结构,或合并 Java 类型)
我目前的想法是:
我认为这会起作用,尽管我担心它开始看起来像是很多“胶水”代码。此外,这可能也反射(reflect)了我对面向对象方法的更熟悉。
在 Clojure 中推荐的方法是什么?
最佳答案
我认为 deftype
可能是要走的路,但是我会通过访问器方法。相反,请查看 clojure.lang.ILookup
和 clojure.lang.Associative
;这些是接口(interface),如果您为您的类型实现它们,将允许您使用 get
/get-in
和 assoc
/assoc-in
,提供了一个更加通用的解决方案(您不仅可以更改底层实现,还可以使用构建在 Clojure 标准集合库之上的函数来操作您的结构)。
有几点需要注意:
defrecord
开始, 使用 get
, assoc
& Co. 与标准 defrecord
ILookup
的实现, Associative
, IPersistentMap
和 java.util.Map
.你也许可以用它走很长的路。如果/当这些还不够时,请查看
emit-defrecord
的来源(在 Clojure 的源代码中 core_deftype.clj
中定义的私有(private)函数)。它非常复杂,但它会让您了解您可能需要实现什么。deftype
也不是 defrecord
目前为您定义任何工厂函数,但您可能应该自己做。健全性检查进入这些功能(和/或相应的测试)。get
基础上的协议(protocol)功能。公司哦,看看
gvec.clj
在 Clojure 的源代码中,有一个使用 deftype
编写的一些严肃的数据结构代码的示例。可能看起来像。这里的复杂性与您在问题中描述的不同,但它仍然是目前可供公众使用的 Clojure 中为数不多的自定义数据结构编程示例之一(当然,它是高质量的代码)。当然,这只是我此时的直觉告诉我的。我不确定现阶段是否有很多已建立的习语,
deftype
实际上并没有被释放。 :-)
关于data-structures - 从 Clojure 中的数据结构实现细节中抽象出来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3110338/