我有一个存储在原子中的集合,就像这样
(def numbers (atom #{1 2 3 4 5}))
Run Code Online (Sandbox Code Playgroud)
使用swap!. 在一个单独的线程中,我想要一个函数,从集合中提取和删除偶数并返回它们。
我可以这样做的一种方法是:
(let [{even true odd false} (group-by even? @numbers)]
(reset! numbers odd)
even)
Run Code Online (Sandbox Code Playgroud)
但是,这不是原子操作。numbers可以在group-by和之间变化reset!。有没有办法以原子方式执行此操作?
应用的函数swap!不需要是原子的。您应该可以使用swap!.
如果您只想留下奇数并取回偶数,您可以通过swap!仅返回赔率来应用该函数,然后这就是原子的值将被更新为的值。
剩下的问题是如何取回偶数。有很多方法可以做到这一点——我不确定什么是最好的。也许您可以在您的收藏中使用元数据?像这样的东西:
(def numbers (atom #{1 2 3 4 5}))
(defn atom-splitter [xs]
(let [{even true odd false} (group-by even? xs)]
(with-meta (set odd) {:evens (set even)})))
(swap! numbers atom-splitter)
Run Code Online (Sandbox Code Playgroud)
的价值@numbers是那么#{1 3 5}。
值(meta @numbers)IS {:evens #{2 4}}。
由于swap!返回的是换入值,因此您可以确定返回值的元数据包含拆分集合的另一半。例如,以下是安全的:
(defn split-off-evens [a]
(-> (swap! numbers atom-splitter) meta :evens))
Run Code Online (Sandbox Code Playgroud)
如果具有其原始值,则调用(split-off-evens numbers)返回。由于这仍然是 的正确用法,您可以假设 Clojure 处理所有线程安全问题。#{2 4}numbersatom
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |