(def history (atom ()))
(defn log->list
[dest-atom key source old new]
(when (not= old new)
(swap! dest-atom conj new)))
(def sarah (atom {:name "Sarah" :age 25}))
(add-watch sarah :record (partial log->list history))
(swap! sarah update-in [:age] inc)
(swap! sarah identity)
(pprint @history)
log->list
函数有两个永远不会被使用的args key
和source
。他们在这里干什么?
答案 0 :(得分:0)
密钥是用于以后删除它的标记:
(remove-watch reference key)
如果该密钥随后被传递给观看功能,那么它一旦被触发就能够在以后将其移除。虽然您可以通过提前同意关键名称来构建它,但具有此功能可以使事情更加优雅。
答案 1 :(得分:0)
来自add-watch的文档字符串:
将watch函数添加到agent / atom / var / ref引用。手表 fn必须是4个参数的fn:一个键,一个参考,它的旧状态,它的 新状态...
因为我们在原子上添加了一个监视,log->list
需要是一个4 arity函数。我们将传递密钥,参考,旧值和新值。即使我们只使用旧值和新值,我们需要在函数中有4个args,因此它具有正确的arity。
在Clojure中,通常使用下划线代替函数定义中未使用的参数来表明它未被使用,并减少视觉噪音。但是在这种情况下,我认为保留未使用的变量并命名它们可以更清楚地发生了什么,并且如果有必要,将来可以更容易地修改它。这一点尤为重要,因为我们需要保持此功能的优点与其一起使用add-watch。在一本书中,我倾向于这个选项。
在实际的代码中它是临界的,我可以在下划线和命名args上的任何一种方式。我选择的内容可能取决于背景以及在清晰度和简洁性方面取得适当平衡的任何内容。