从 Clojure 中的数据结构实现细节中抽象出来 [英] Abstracting away from data structure implementation details in Clojure
问题描述
我正在 Clojure 中开发具有多个子结构的复杂数据结构.
我知道随着时间的推移我会想要扩展这个结构,并且有时可能想要改变内部结构而不破坏数据结构的不同用户(例如我可能想要将向量更改为哈希图,添加一些一种出于性能原因的索引结构,或包含 Java 类型)
我目前的想法是:
- 为具有各种访问器方法的整体结构定义一个协议
- 创建一个小型函数库来导航数据结构,例如(查询子结构-abc param1 param2)
- 使用 defrecord 或 deftype 实现数据结构,并定义协议方法以使用迷你库
我认为这会起作用,但我担心它开始看起来像很多胶水"代码.此外,这可能也反映了我对面向对象方法的更熟悉.
在 Clojure 中推荐的执行此操作的方法是什么?
我认为 deftype
可能是要走的路,但是我会通过访问器方法.相反,查看 clojure.lang.ILookup
和 clojure.lang.Associative
;这些是接口,如果您为您的类型实现它们,将允许您使用 get
/get-in
和 assoc
/assoc-in
,提供更通用的解决方案(您不仅可以更改底层实现,还可以使用构建在 Clojure 标准集合库之上的函数来操作您的结构).
需要注意的几点:
您可能应该从
defrecord
开始,使用get
、assoc
&Co. 与ILookup
、Associative
、IPersistentMap
和java.util.Map 的标准
defrecord
实现代码>.你也许可以走很长的路.如果/当这些还不够时,请查看
emit-defrecord
的源代码(Clojure 源代码中core_deftype.clj
中定义的私有函数).这非常复杂,但它会让您了解可能需要实施的内容.deftype
和defrecord
目前都没有为您定义任何工厂函数,但您可能应该自己做.健全性检查在这些函数(和/或相应的测试)中进行.概念上更复杂的操作当然非常适合建立在
get
& 基础上的协议函数.公司
哦,查看 Clojure 源代码中的 gvec.clj
示例,了解使用 deftype
编写的一些严肃的数据结构代码可能是什么样子.这里的复杂性与您在问题中描述的不同,但它仍然是目前可供公众使用的 Clojure 中的自定义数据结构编程的少数示例之一(当然,它是优质的代码).>
当然,这只是我此时的直觉告诉我的.我不确定现阶段是否有很多已建立的习语,deftype
实际上还没有发布等等.:-)
I am developing a complex data structure in Clojure with multiple sub-structures.
I know that I will want to extend this structure over time, and may at times want to change the internal structure without breaking different users of the data structure (for example I may want to change a vector into a hashmap, add some kind of indexing structure for performance reasons, or incorporate a Java type)
My current thinking is:
- Define a protocol for the overall structure with various accessor methods
- Create a mini-library of functions that navigate the data structure e.g. (query-substructure-abc param1 param2)
- Implement the data structure using defrecord or deftype, with the protocol methods defined to use the mini-library
I think this will work, though I'm worried it is starting to look like rather a lot of "glue" code. Also it probably also reflects my greater familiarity with object-oriented approaches.
What is the recommended way to do this in Clojure?
I think that deftype
might be the way to go, however I'd take a pass on the accessor methods. Instead, look into clojure.lang.ILookup
and clojure.lang.Associative
; these are interfaces which, if you implement them for your type, will let you use get
/ get-in
and assoc
/ assoc-in
, making for a far more versatile solution (not only will you be able to change the underlying implementation, but perhaps also to use functions built on top of Clojure's standard collections library to manipulate your structures).
A couple of things to note:
You should probably start with
defrecord
, usingget
,assoc
& Co. with the standarddefrecord
implementations ofILookup
,Associative
,IPersistentMap
andjava.util.Map
. You might be able to go a pretty long way with it.If/when these are no longer enough, have a look at the sources for
emit-defrecord
(a private function defined incore_deftype.clj
in Clojure's sources). It's pretty complex, but it will give you an idea of what you may need to implement.Neither
deftype
nordefrecord
currently define any factory functions for you, but you should probably do it yourself. Sanity checking goes inside those functions (and/or the corresponding tests).The more conceptually complex operations are of course a perfect fit for protocol functions built on the foundation of
get
& Co.
Oh, and have a look at gvec.clj
in Clojure's sources for an example of what some serious data structure code written using deftype
might look like. The complexity here is of a different kind from what you describe in the question, but still, it's one of the few examples of custom data structure programming in Clojure currently available for public consumption (and it is of course excellent quality code).
Of course this is just what my intuition tells me at this time. I'm not sure that there is much in the way of established idioms at this stage, what with deftype
not actually having been released and all. :-)
这篇关于从 Clojure 中的数据结构实现细节中抽象出来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!