3

比较 和 的源代码clojure.lang.Refclojure.lang.Atom我发现它们都继承自clojure.lang.ARef.

其中clojure.lang.ARef有一个功能notifyWatches可以让所有手表功能都知道已经进行了更改。

swap!reset!函数在其实现中的clojure.lang.Atom调用。notifyWatches

例如。

public Object swap(IFn f) {
for(; ;)
    {
    Object v = deref();
    Object newv = f.invoke(v);
    validate(newv);
    if(state.compareAndSet(v, newv))
        {
        notifyWatches(v, newv);
        return newv;
        }
    }
 }

但是,当我搜索notifyWatchesin 时clojure.lang.Ref,它什么也没有。alter函数看起来像这样。

public Object alter(IFn fn, ISeq args) {
   LockingTransaction t = LockingTransaction.getEx();
   return t.doSet(this, fn.applyTo(RT.cons(t.doGet(this), args)));
}

如果没有方法调用 notifyWatches,如何通知 ref 的所有 watch 函数?

4

2 回答 2

3

notifyWatches您正在寻找的调用发生在类的run方法中LockingTransaction

对 refs 的更改发生在事务中。请注意,传递了对doSet方法的调用(对 Ref 的引用)。在事务中应用的更改由 方法确定,但该更改在 的方法中生效。当事务成功运行时,使用对 Ref 记录的引用调用。LockingTransactionthisdoSetrunLockingTransactionnotifyWatchesdoSet

于 2012-11-14T12:59:13.193 回答
2

clojure.lang.Ref扩展了具有手表并提供 notifyWatches 方法的clojure.lang.ARef

于 2012-11-14T01:34:45.997 回答