Clojure:检查两个原子之间具有相同键的值是否相等(使用 add-watch)
Clojure: Checking equality of values with the same key across two atoms (using add-watch)
假设我有一个原子:
(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
发生变化时收到通知怎么办?当我尝试比较取消引用原子的属性时出现错误:
; 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
的更改?
你的例子中只有一个原子。
您不需要在监视函数中取消引用 os 和 ns,因为它获取原子的旧值和新值而不是原子本身。只需删除代码中的 @ 符号即可。
假设我有一个原子:
(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
发生变化时收到通知怎么办?当我尝试比较取消引用原子的属性时出现错误:
; 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
的更改?
你的例子中只有一个原子。
您不需要在监视函数中取消引用 os 和 ns,因为它获取原子的旧值和新值而不是原子本身。只需删除代码中的 @ 符号即可。