PersistentQueue的API是什么?

问题描述 投票:2回答:2

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是否记录在任何地方,甚至是非正式的? (“我的回答中只有完整的文档记录”很好。真的,我希望有人会在答案中写下缺失的文档,或者说如果没有丢失则告诉在哪里找到它。)

data-structures clojure queue
2个回答
4
投票

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

通常,与队列一起使用的正确操作是conjintopeekpop

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

0
投票

顺序集合的协议是

  • (conj coll x) - 返回集合collx添加到一端或另一端;
  • (peek coll) - 返回下一个要从coll丢弃的项目,如果有的话;
  • (pop coll) - 返回coll减去丢弃的结束。

peekpop总是在同一端工作:

  • 列表的前面(或一般序列);
  • 矢量或队列的背面。

conj与向量或列表的peek / pop在同一端,但在队列的另一端(前面)。这就是它作为队列工作的原因。

如前所述,getdisj与顺序集合无关。

您可能会感到困惑,因为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)
© www.soinside.com 2019 - 2024. All rights reserved.