gpt4 book ai didi

clojure - 从 Clojure 向量原子中删除第一项并将其返回

转载 作者:行者123 更新时间:2023-12-02 09:31:09 25 4
gpt4 key购买 nike

我有一个原子包裹着一个项目向量:

(def items (atom [1 2 3 4]))

我想自动删除第一项并将其返回。此代码说明了逻辑:

(let [x (first @items)]
(swap! items #(subvec % 1))
x)

但是当多个线程相互竞争时,上面的代码是不正确的。读取和更新之间存在竞争条件。

正如 this answer 中所说的那样,原子用于不协调的同步访问。我希望这可以用原子而不是引用来完成,因为原子更简单。

是否有一种仅使用原子而不使用引用的解决方案? (我将尝试使用 watch ,看看情况如何。)如果您的答案坚持认为需要 ref,请您解释一下为什么需要 ref,即使当人们想要“协调同步访问多个身份”时建议使用 ref “(与上面相同的链接)。

这与其他相关问题不同,例如 How do I update a vector element of an atom in Clojure?Best way to remove item in a list for an atom in Clojure因为我想更新矢量原子返回值。

最佳答案

带有compareAndSet的自旋循环用于交换!原子。 Clojure 还为原子提供了较低级别的 compare-and-set!,您可以使用它来执行自己的自旋循环并返回旧值和新值。

(defn swap*!
"Like swap! but returns a vector of [old-value new-value]"
[atom f & args]
(loop []
(let [ov @atom
nv (apply f ov args)]
(if (compare-and-set! atom ov nv)
[ov nv]
(recur)))))

(defn remove-first-and-return [atom]
(let [[ov nv] (swap*! atom subvec 1)]
(first ov)))

关于clojure - 从 Clojure 向量原子中删除第一项并将其返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22409638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com