PersistentQueue的API是什么?
天真地,它似乎丢失了任何数据:
user=> (def q (into (clojure.lang.PersistentQueue/EMPTY)
(repeat 5 nil)))
#'user/q
user=> (def q2 (pop (conj q :a)))
#'user/q2
user=> (get q2 4)
nil
user=> (get q2 0)
nil
我不能正确访问PersistentQueue。显然它不适用于get
。访问PersistentQueue的正确方法是什么?你能用它做什么?
PersistentQueue是否记录在任何地方,甚至是非正式的? (“我的回答中只有完整的文档记录”很好。真的,我希望有人会在答案中写下缺失的文档,或者说如果没有丢失则告诉在哪里找到它。)
conj
从不改变它的参数,它返回一个不可变的新数据结构,并且可以在内部与原始数据共享数据。但我想你已经知道了这一部分。
get
仅适用于关联数据,如果在非关联数据上使用,则返回nil而不是错误。队列不是关联的。通过将nil放入队列中,这个问题在您的示例中被部分掩盖,这使得get
返回的nil不明确。
user=> (def q (into clojure.lang.PersistentQueue/EMPTY (repeat 5 :a)))
#'user/q
user=> (into [] q)
[:a :a :a :a :a]
user=> (def q2 (pop (conj q :b)))
#'user/q2
user=> (into [] q2)
[:a :a :a :a :b]
user=> (get q2 4)
nil
user=> (get q2 0)
nil
user=> (nth q2 4)
:b
user=> (nth q2 0)
:a
通常,与队列一起使用的正确操作是conj
,into
,peek
和pop
。
user=> (def q3 (-> q2 (pop)
(conj :c :d)
(pop)
(conj :e)
(pop)
(pop)
(conj :f)))
#'user/q3
user=> (into [] q3)
[:b :c :d :e :f]
user=> (peek q3)
:b
顺序集合的协议是
(conj coll x)
- 返回集合coll
与x
添加到一端或另一端;(peek coll)
- 返回下一个要从coll
丢弃的项目,如果有的话;(pop coll)
- 返回coll
减去丢弃的结束。peek
和pop
总是在同一端工作:
conj
与向量或列表的peek
/ pop
在同一端,但在队列的另一端(前面)。这就是它作为队列工作的原因。
如前所述,get
和disj
与顺序集合无关。
您可能会感到困惑,因为PersistentQueue
不知道如何正确地将自己转换为字符串。 seq
将告诉你你有什么。例如,
(def q (into (clojure.lang.PersistentQueue/EMPTY)
(repeat 5 nil)))
q ;=>#<PersistentQueue clojure.lang.PersistentQueue@1b4d89f>
(seq q) ;(nil nil nil nil nil)