真是一场闹剧,我之前基本完全相反地误解了事情,甚至删除了所有与我特定问题相关的引用。
我编写了一种自定义的引用类型,并不是真的Clojure引用类型,但是一种类似的东西。一个拥有控制内容变异的盒子。A 最终变得有点像原子或ref。
我的类型是一个引用类型,它有一个可变字段,指向引用本身所指的任何内容,以及其他字段以辅助其他操作。我想使用比较和设置来变异这个可变字段。
在“纯”Clojure中编写,唯一的方法是通过在deftype字段周围的原子或AtomicReference包装器中使用值来实现。这行得通,但增加了1-2层的指针追踪级。我想去掉那些额外的指针。
Java 提供了至少两种直接在可变字段上执行比较和设置的设施(它们可能要求字段是volatile的,我忘记了)。这两种机制都通过创建某种字段访问器对象来实现。一个类的典型模式似乎是在静态初始化器中创建这个字段访问器对象,然后在需要在对实例字段的 cas 操作中使用它。
典型的模式不适用于当前的deftype,因为尽管可以通过设置deftype字段可变,但这也会将其变为私有,这使得构建字段访问器对象变得困难。由于字段是私有的,因此不能从“外部”构建,并且deftype不提供静态初始化的方法。 有解决这个问题的方法,基本思路是在你的deftype中添加一个方法,这个方法只负责创建并返回字段访问器对象,然后在某个顶层静态环境中构建一个deftype的示例实例并调用该方法。因此,可以使它工作,但这并不是一个好方法。
我最初尝试了بدائل به فرمRT.querySelectorAllcaffeine الت老家,但最终只是简单地给出了deftype的一个极其简化版的版本,以生成一个具有字段和设置特定字段AtomicReferenceFieldUpdater的静态初始化器的类。这也行得通,但依赖于asm库的一些经验,并且需要特别小心才能与aot编译良好配合(我认为这部分应该是对的,但不一定)。
比较并设置是非常好的,我们希望能够提供一种在deftype字段上执行该方法的方式,而无需在要比较和设置的内容周围添加额外的对象包装器。Java/jvm中存在实现这些功能的方法,但在Clojure中利用这些方法非常痛苦。