Clojure:在两个原子上用相同的键检查值的相等性(使用add-watch)

时间:2016-04-09 02:57:57

标签: clojure clojurescript

我们说我有一个原子:

(def pets (atom { :cats {} :dogs {} }))

我想看这个原子进行更改,所以我创建了一个观察者:

(add-watch pets :pet-watcher
  (fn [r k os ns]
    (when (not= os ns
      (println (str "Pets updated: " ns) )))))

现在,如果我更新我的宠物原子,我会收到更改通知:

(swap! pets assoc-in [:dogs] {:name "Sparky" :color "Brown"})

; Pets updated: {:cats {}, :dogs {:name "Sparky", :color "Brown"}}

但是,如果:cats发生变化,我只想收到通知怎么办?当我尝试比较deref' d atoms的属性时出错:

; THIS DOES NOT WORK
(add-watch pets :cat-watcher
  (fn [r k os ns]
    (when (not= (:cats @os) (:cats @ns)
      (println (str "Cats updated: " (:cats @ns)) )))))

(swap! pets assoc-in [:cats] {:name "Whiskers" :color "Orange"})

; Error: No protocol method IDeref.-deref defined for type cljs.core/PersistentArrayMap

必须有一种优雅的方法来比较两个原子上相同键的值。您如何更新我的:cat-watcher以通知我:cats的更改?

1 个答案:

答案 0 :(得分:4)

您的示例中只有一个原子。

您不需要在观察函数中取消引用os和ns,因为它获取原子的旧值和新值而不是原子本身。只需删除代码中的@符号即可。