(def alice-height
(ref 3))
(def right-hand-bites
(ref 10))
(defn eat-from-right-hand []
(dosync
(when (pos? @right-hand-bites)
(alter right-hand-bites dec)
(alter alice-height #(+ % 24)))))
这段代码来自于《Living Clojure》一书。在书中,作者还给出了一个使用commute替换alter的例子。我想知道,在开头的pos?
测试中,我们真的能进行这个替换吗?
(when (pos? @right-hand-bites) ...)
中读取的问题。right-hand-bites
上的deref
不在commute
内,应在提交之前受到快照一致性的限制。因此,在读取期间如果条件看到了正数的right-hand-bites
,那么在提交之前它应该保证有一个一致的值。如果条件在commute
内部,则情况会改变。 - A. Webbensure
。这里再次是问题的关键:commute
在提交期间(仍处于事务中)重新读取引用的_当前值_(快照之外的值!),然后_无条件地_重新应用通勤函数。这就是它成为检查-然后-操作错误的地方。在REPL中尝试自己验证并不太困难。 - glts