摘要远离Clojure中的数据结构实现细节

时间:2010-06-24 13:26:41

标签: data-structures clojure encapsulation abstraction

我正在Clojure中开发一个具有多个子结构的复杂数据结构。

我知道我会希望随着时间的推移扩展这个结构,有时可能想要更改内部结构而不会破坏数据结构的不同用户(例如我可能想要将一个向量更改为一个hashmap,添加一些出于性能原因,或者采用Java类型的索引结构

我目前的想法是:

  • 使用各种访问方法定义整体结构的协议
  • 创建一个导航数据结构的迷你函数库,例如(query-substructure-abc param1 param2)
  • 使用defrecord或deftype实现数据结构,定义协议方法以使用迷你库

我认为这会有效,但我担心它开始看起来像很多“胶水”代码。它也可能反映了我对面向对象方法的更多熟悉。

在Clojure中推荐的方法是什么?

1 个答案:

答案 0 :(得分:11)

我认为deftype可能是要走的路,但是我会对访问器方法进行传递。相反,请查看clojure.lang.ILookupclojure.lang.Associative;这些接口如果您为您的类型实现它们,将允许您使用get / get-inassoc / assoc-in,从而提供更通用的解决方案(不是只有你能够改变底层实现,但也许你也可以使用在Clojure标准集合库之上构建的函数来操作你的结构。

有几点需要注意:

  1. 您应该从defrecord开始,使用getassoc&具有defrecordILookupAssociativeIPersistentMap的标准java.util.Map实施的公司。你可能会用它走很长的路。

    如果/当这些不再足够时,请查看emit-defrecord的来源(Clojure来源中core_deftype.clj中定义的私有函数)。它非常复杂,但它可以让您了解可能需要实施的内容。

  2. deftypedefrecord目前都没有为您定义任何工厂功能,但您应该自己动手。完整性检查进入这些功能(和/或相应的测试)。

  3. 概念上越复杂的操作当然非常适合建立在get&基础之上的协议功能。有限公司

  4. 哦,在Clojure的源代码中查看gvec.clj,了解一些使用deftype编写的严肃数据结构代码的示例。这里的复杂性与您在问题中描述的不同,但它仍然是Clojure中目前可供公众使用的少数自定义数据结构编程示例之一(当然它也是优质代码)。

    当然,这正是我的直觉告诉我的。我不确定在这个阶段已经存在很多成熟习语的方式,deftype实际上没有被释放的所有内容。 : - )