真是出丑,我之前基本上误解了相反的意思,并删除了我具体问题中所有的引用。
我编写了一种自定义类型的引用类型,其实并不是Clojure的引用类型,而是一种类似的东西。一个带有内容控制的方盒引证类型。A最终变得略微像原子或引用。
我的类型作为一个引用类型,有一个可以指向引用本身指向的内容的可变字段,以及其他辅助操作的字段。我想使用比较和设置来修改这个可变字段。
在“纯Clojure”中编写,唯一的方法是通过在deftype字段中使用atom或AtomicReference包装器来持有值。这可以工作,但会增加1或2层指针追踪。我想去掉这些额外的指针。
Java提供了至少两种直接在可变字段上进行比较和设置的方法(可能需要该字段是volatile的,我忘了)。这两种机制都是通过创建一种类型的字段访问对象来实现的。一个类的典型模式似乎是在静态初始化器中创建字段访问对象,然后在需要对该实例的字段进行cas操作时使用它。
典型的模式不适用于当前的deftype,因为尽管您可以使得deftype字段可变,但这也会使其成为私有,从而难以构造字段访问对象。由于字段是私有的,所以您不能从“外部”构造它,并且deftype没有提供进行静态初始化的方法。有办法绕过这个问题,基本上是在您的deftype中添加一个什么也不做的方法,创建并返回字段访问对象,然后在某些顶层静态上下文中构造一个您的deftype的空实例并调用该方法。因此,这样做是可行的,但很糟糕。
我开始尝试构造空的deftype实例,但最终只写了一个极度简化的deftype版本,用于生成具有字段和设置特定字段AtomicReferenceFieldUpdater的静态初始化器的类。这也可行,但这依赖于对asm库的一些经验,并且需要小心以良好地配合aot编译(我认为我已经处理对了,但不确定)。
比较和设置很棒,如果能提供一种方法在deftype字段上进行比较和设置,而不需要对想要比较和设置的值添加额外的对象包装,那就更好了。在Java/jvm中存在实现这种方法的机制,但在Clojure中利用这些机制很痛苦。