如果我使用 Clojure 原子来计算某些东西(例如投票),我可以这样做:
(def votes (atom {}))
(defn vote! [candidate]
(swap! votes update-in [candidate] (fnil inc 0)))
(vote! "Abraham Lincoln")
(vote! "Abraham Lincoln")
(vote! "Winston Churchill")
votes ;=> {"Abraham Lincoln" 2, "Winston Churchill" 2}
在这里,update-in
巧妙地转换给定键的值,而不必先查找它。
我怎样才能在 Datomic 中完成同样的任务?我可以做这样的事情......
(defn vote! [db candidate]
(let [[e v] (first (q '[:find ?e ?v
:in $ ?candidate
:where [[?e :name ?candidate]
[?e :votes ?v]] db candidate)
(transact! conn [{:db/id e :votes (inc v)}]))
但这似乎有点麻烦,必须运行查询,返回值,然后与新值进行交易。有没有更惯用的方法(如 aswap!
或update-in
)?