PersistentQueue的API是什么?

时间:2016-06-05 17:34:56

标签: data-structures clojure queue

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

顺序集合的协议是

  • (conj coll x) - 将coll添加到一端或另一端的归档集x;
  • (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)