Clojure的四种基础数据结构
在Clojure Programming一书1当中,介绍了Clojure的四种数据结构。本文是读书笔记,附加一些Clojure源代码分析。
Clojure的四种基础数据结构:
- Maps
- Vectors
- Sets
- Lists
代码举例(来自Clojure Programming书中:Chapter 3 Collections and Data Structures):
'(a b :name 12.5) ;; list
['a 'b :name 12.5] ;; vector
{:name "Chas" :age 31} ;; map
#{1 2 3} ;; set
我们可以查看上面的数据结构对应的Clojure实现classes:
user=> (class '(a b :name 12.5))
clojure.lang.PersistentList
user=> (class ['a 'b :name 12.5])
clojure.lang.PersistentVector
user=> (class {:name "Chas" :age 31})
clojure.lang.PersistentArrayMap
user=> (class #{1 2 3})
clojure.lang.PersistentHashSet
从上面的代码2,我们可以看到数据类型对应的Clojure classes。
在实现上面的4种数据结构之下,Clojure包含有7种抽象的数据类型:
- Collection
- Sequence
- Associative
- Indexed
- Stack
- Set
- Sorted
上面这些抽象模型体现在Clojure的实现代码当中,就是各个接口的定义。比如Collection类型,在Clojure Programming一书当中(Chapter 3 Collections and Data Structures - Abstractions over Implementations - Collection)给出的定义如下:
All data structures in Clojure participate in the common collection abstraction. A collection is a value that you can use with the set of core collection functions:
- conj to add an item to a collection
- seq to get a sequence of a collection
- count to get the number of items in a collection
- empty to obtain an empty instance of the same type as a provided collection
- = to determine value equality of a collection compared to one or more other collections
上面这些定义都可以在Clojure的源代码种找到对应的接口和相关方法。下面是相关接口:
- clojure.lang.IPersistentCollection
- clojure.lang.Seqable
- clojure.lang.ISeq
下面这幅图展现了这些接口之间的extends关系,以及接口中的方法定义:
注意上面这些接口重的方法定义,这些方法决定了Clojure的数据结构的设计思路和使用方法。
在IPersistentCollection之下,我们可以看到更为细分的接口类型:
从上面的图中可以看到Stack,Set,Vector,Seq之间的关系。其中ISeq类型是Clojure设计当中很重要的一类数据。我们可以重点看一下ISeq接口和相关的实现:
在上面的设计当中,LazySeq是会在后续文章里面重点说明的对象。