我正在尝试更新原子内部的映射。每个映射都由一个值引用。
(def a (atom {}))
(defn foo [id mps]
(let [x (merge (get mps id) mps)]
(swap! a assoc id x) x))
(foo 2 {:baz 88}) => {:baz 88}
@a => {2 {:baz 88}}
(foo 2 {:bar 99}) => {:bar 99} ??
@a => {2 {:bar 99}} ??
它似乎覆盖了地图,而不是更新它。我正在寻找的结果是:
(foo 2 {:baz 88}) => {:baz 88}
@a => {2 {:baz 88}}
(foo 2 {:bar 99}) => {:bar 99, :baz 88}
@a => {2 {:bar 99, :baz 88}}
任何帮助都将是伟大的
您正在用新值替换旧值(使用assoc
)。你要找的是merge-with
的行为(http://conj.io/store/v1/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/merge-with/)直接作用在原子上。类似:
user=> (def a (atom {}))
#'user/a
user=> (swap! a #(merge-with merge % {:a {:b 1}}))
{:a {:b 1}}
user=> (swap! a #(merge-with merge % {:a {:c 2}}))
{:a {:c 2, :b 1}}