在ref中弹出PersistentQueue的惯用方法是什么?

时间:2011-02-03 19:52:18

标签: concurrency clojure queue

在ref:

中给出PersistentQueue
(def pq (ref clojure.lang.PersistentQueue/EMPTY))

弹出队列并获得结果的惯用方法是什么?

我对你的批评的最佳尝试:

(defn qpop [queue-ref]
    (dosync 
        (let [item (peek @queue-ref)]
          (alter queue-ref pop)
          item))

alter返回已经弹出的队列的事务内值,因此您不能单独执行alter。

2 个答案:

答案 0 :(得分:5)

我想不出更抽象你的dosync体的更惯用的东西。

但是,如果您正在进行特技表演,可以尝试逐个黑客:始终将PQ的头部视为垃圾(它包含以前弹出的项目)。因此,您可以重写qpop

(defn qpop [queue-ref]
  (peek (alter queue-ref pop))

它会增加对空虚的特殊检查(特别是当你结合时)。它还意味着保持对项目的引用的时间超过它应该的时间(但是如果你看一下PQ的impl,你会看到它通过itsef它可能会长时间引用弹出的项目,所以活力已经是模糊的)。

我使用了这个hack here

答案 1 :(得分:1)

使用Common Lisp的prog1宏可以简化你的dosync体,虽然核心Clojure似乎缺乏它。有一个简单的实现on the Google group,以及如何在Clojure中使它成为一个函数(而不是宏)的讨论。