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是否记录在任何地方,甚至是非正式的? (“我的答案中只有完整的记录”很好。真的,我希望有人会在答案中写下遗失的文件,或者说如果它没有遗漏就知道在哪里找到它。)
答案 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
通常,与队列一起使用的正确操作是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
答案 1 :(得分:0)
顺序集合的协议是
(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)