裁判如何通过clojure通知其手表?

时间:2012-11-14 00:14:45

标签: clojure

比较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;
        }
    }
 }

但是,当我在notifyWatches中搜索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函数如何得到通知?

2 个答案:

答案 0 :(得分:3)

您要查找的notifyWatches来自run类的LockingTransaction方法。

对交易的更改发生在交易中。请注意,对doSet LockingTransaction方法的调用已通过this(对Ref的引用)。在事务中应用的更改由doSet方法确定,但该更改在run LockingTransaction方法中生效。成功运行交易时notifyWatches使用对doSet记录的参考号的引用进行调用。

答案 1 :(得分:2)

clojure.lang.Ref扩展clojure.lang.ARef the watches并提供notifyWatches方法