Clojure交换!原子出队 [英] Clojure swap! atom dequeuing

查看:71
本文介绍了Clojure交换!原子出队的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种更简单的方法在Clojure中编写此代码:

Is there a simpler way to write this code in Clojure :

(def queue (atom {:top nil :queue PersistentQueue/EMPTY}))
(swap! queue #(hash-map :top nil :queue (conj (:queue %) "foo")))
(let [{:keys [top]} (swap! queue
                        #(hash-map 
                           :top (peek (:queue %)) 
                           :queue (pop (:queue %))))]
  (println top))

另一种写法是:

(def queue (atom PersistentQueue/EMPTY))
(swap! queue conj "foo")
(let [top (atom nil)]
  (swap! queue 
         (fn [queue]
           (reset! top (peek queue))
           (pop queue)))
  (println @top))

这似乎更糟。

无论如何,我有一个使用原子进行大量排队的代码,使用前一种方法会使代码真正令人困惑,我希望会有一些像这样的东西:

Anyway I have a code which uses atoms for queuing a lot and using the former approach is making the code really confusing, I would expect there to be something like :

(swap! queue (fn [queue] (AtomSwapResult. atom-value return-value))

或某些类似的机制在交换!函数,因为这似乎是您经常想做的事情(甚至不限于排队,我还遇到了其他一些用例,返回不同的值会很有用,例如交换的旧值),并且不会破坏原子/交换!

or some similar mechanism in the swap! function since it seems like the kind of thing you would want to do often (not even limited to queuing, I've hit several other use cases where it would be useful to return a different value, for eg. the old value that was swapped out) and it doesn't break the atom/swap! semantics.

在Clojure中是否可以做到这一点?

Is there a way to do this in Clojure ?

推荐答案

(defn dequeue!
  [queue]
  (loop []
    (let [q     @queue
          value (peek q)
          nq    (pop q)]
      (if (compare-and-set! queue q nq)
        value
        (recur)))))

(def queue (atom clojure.lang.PersistentQueue/EMPTY))
(swap! queue conj :foo)
(swap! queue conj :bar)
(seq @queue)
(dequeue! queue)
(seq @queue)

这篇关于Clojure交换!原子出队的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆