应该完全禁止在可变域上关闭(并生成编译器异常),而不仅仅是尝试使用 set! 设置它们。因为可变域的变化不会传播到闭包中,这会导致令人惊讶的错误。
`
(defprotocol P
(-set [this])
(-get [this])
(-get-fn [this]))
(deftype T [^:unsynchronized-mutable val]
P
(-set [this] (set! val :bar))
(-get [this] val)
(-get-fn [this] (fn [] val)))
(def x (->T :foo))
(def xf (-get-fn x))
user> (-set x)
:bar
user> (-get x)
:bar
user> (xf)
:foo ;; 应该是 :bar !!!
`