Collections 什么';Clojure中序列和集合的区别是什么
我是一名Java程序员,是Clojure的新手。从不同的地方,我看到序列和集合在不同的情况下使用。然而,我不知道他们之间的确切区别是什么 例如: 1) 在Clojure的文件中: 如您所见,在描述Seq接口时,前两个函数(first/rest)使用Collections 什么';Clojure中序列和集合的区别是什么,collections,clojure,abstraction,Collections,Clojure,Abstraction,我是一名Java程序员,是Clojure的新手。从不同的地方,我看到序列和集合在不同的情况下使用。然而,我不知道他们之间的确切区别是什么 例如: 1) 在Clojure的文件中: 如您所见,在描述Seq接口时,前两个函数(first/rest)使用coll,这似乎表明这是一个集合,而cons函数使用Seq,这似乎表明这是一个序列 2) 有称为coll?和seq?的函数可用于测试值是集合还是序列。很明显,收集和顺序是不同的 3) Clojure关于“”的文档中说: 因为集合支持seq函数,所以所有
coll
,这似乎表明这是一个集合,而cons
函数使用Seq
,这似乎表明这是一个序列
2) 有称为coll?
和seq?
的函数可用于测试值是集合还是序列。很明显,收集和顺序是不同的
3) Clojure关于“”的文档中说:
因为集合支持seq函数,所以所有序列
函数可以与任何集合一起使用
这是否意味着所有集合都是序列
(coll? [1 2 3]) ; => true
(seq? [1 2 3]) ; => false
上面的代码告诉我情况并非如此,因为[1 2 3]
是一个集合,但不是序列
我认为这对Clojure来说是一个非常基本的问题,但我无法找到一个地方来清楚地解释它们的区别是什么,在不同的情况下应该使用哪一个。欢迎发表任何评论。任何支持核心
第一
和其余
功能的对象都是序列
许多对象满足此接口,每个Clojure集合都提供至少一种seq对象,用于使用seq
函数遍历其内容
因此:
您还可以从映射创建序列对象
user> (seq {:a 1 :b 2})
([:a 1] [:b 2])
这就是为什么您可以在映射上使用过滤器
,映射
,for
,等等
因此,可以将许多类似集合的对象视为序列
这也是为什么许多序列处理函数,如输入上的filter
callseq
:
(defn filter
"Returns a lazy sequence of the items in coll for which
(pred item) returns true. pred must be free of side-effects."
{:added "1.0"
:static true}
([pred coll]
(lazy-seq
(when-let [s (seq coll)]
如果您调用(filter pred 5)
您可以看到,seq
调用是该对象是否为序列验证的关键
如果你想更深入一点的话,大部分内容都在第5章中。每个序列都是一个集合,但不是每个集合都是一个序列
seq
函数可以将集合转换为序列。例如,对于地图,您可以获得其条目列表。该条目列表与地图本身不同。用于:
如果x实现ISeq,则返回true
用于:
如果x实现IPersistentCollection,则返回true
我在Clojure源代码中发现了IPersistentCollection的扩展,正如Rörd所说,每个序列都是一个集合。作者以一种真正可以理解的方式总结了它:
集合抽象与序列密切相关
抽象。Clojure的所有核心数据结构-向量、地图、,
列表和集合-参与两种抽象
抽象的不同之处在于序列抽象是“关于”
在收集抽象完成时单独对成员进行操作
“关于”整个数据结构。例如,集合
函数count
、empty?
和every?
与任何个人无关
元素;它们是关于整体的
以下几点有助于理解收集和序列之间的区别
“Collection”和“Sequence”是抽象概念,不是可以从给定值确定的属性
收藏是价值的袋子
Sequence是一种数据结构(集合的子集),预期以顺序(线性)方式访问
下图最好地描述了它们之间的关系:
你可以阅读更多有关它的内容。我刚刚阅读了《Clojure之乐》的第5章-“收藏类型”,这有点让人困惑(即,该书的下一版本需要审查)。在第5章第86页,有一个表格我并不完全满意:
这是我的观点(经过一个月的思考后,我回到这一点上,完全更新了)
收集
这是一个“东西”,是其他东西的集合
这基于函数coll?
- 可以使用函数
coll?
对此进行测试
- 相反地,
coll?
返回true的任何内容都是一个集合李>
coll?
docstring说明:
如果x实现IPersistentCollection
将集合分为三个独立类的事物。不同阶级的事物永远不平等
- 使用
(map?foo)
- Map(两个实际实现,行为略有不同)
- 分类地图。注意:
(顺序)(排序映射:A1)
;=>错误
- 使用
(set?foo)
- 设置
- 排序集。注意:
(顺序)(排序集:a:b))
;=>错误
- 使用
(Sequential?foo)
- 名单
- 载体
- 排队
- Seq:
(顺序)(Seq[1 2 3])
;=>正确
- 惰性序列:
(顺序)(惰性序列(序列[1 2 3]))
;=>true
Java互操作的内容不在此范围内:
(coll?(到数组[1 2 3])
;=>错误
(map?(doto(新java.util.HashMap)(.put“a”1)(.put“b”2)))
;=>false
顺序收集(一条“链”)
它是一个“东西”,一个集合,按照特定的、稳定的顺序存放其他东西
这是基于函数sequential?
- 函数
顺序?
user> (seq {:a 1 :b 2})
([:a 1] [:b 2])
(defn filter
"Returns a lazy sequence of the items in coll for which
(pred item) returns true. pred must be free of side-effects."
{:added "1.0"
:static true}
([pred coll]
(lazy-seq
(when-let [s (seq coll)]
Don't know how to create ISeq from: java.lang.Long
RT.java:505 clojure.lang.RT.seqFrom
RT.java:486 clojure.lang.RT.seq
core.clj:133 clojure.core/seq
core.clj:2523 clojure.core/filter[fn]
(def empty-seq (rest (seq [:x])))
(type? empty-seq) ;=> clojure.lang.PersistentList$EmptyList
(nil? empty-seq) ;=> false ... empty seq is not nil
(some? empty-seq) ;=> true ("true if x is not nil, false otherwise.")
(first empty-seq) ;=> nil ... first of empty seq is nil ("does not exist"); beware confusing this with a nil in a nonempty list!
(next empty-seq) ;=> nil ... "next" of empty seq is nil
(rest empty-seq) ;=> () ... "rest" of empty seq is the empty seq
(type (rest empty-seq)) ;=> clojure.lang.PersistentList$EmptyList
(seq? (rest empty-seq)) ;=> true
(= (rest empty-seq) empty-seq) ;=> true
(count empty-seq) ;=> 0
(empty? empty-seq) ;=> true