Clojure 在垃圾收集之前执行操作

Clojure 在垃圾收集之前执行操作,clojure,reference,garbage-collection,pure-function,Clojure,Reference,Garbage Collection,Pure Function,我希望在不再有对某个实体的任何引用之后,但在垃圾收集器清除其数据之前,对该实体执行一些操作。我用它来做一个实验,用更多的“纯功能”gui抽象。以下是我想做的: (let [window (make-window width height)] ; A (various-actions window) (let [window (resize window new-width new-height)] ; B (more-actions window)) (and-more-ac

我希望在不再有对某个实体的任何引用之后,但在垃圾收集器清除其数据之前,对该实体执行一些操作。我用它来做一个实验,用更多的“纯功能”gui抽象。以下是我想做的:

(let [window (make-window width height)] ; A
  (various-actions window)
  (let [window (resize window new-width new-height)] ; B
    (more-actions window))
  (and-more-actions window)) ; C
此时,将创建具有宽度和高度的窗实例。最后,我想在B处更改窗口。代码将此视为一个不可变的操作,但窗口下面的更改只是为了反映更改。当B作用域的窗口存在时(在多线程的情况下),在A作用域的窗口上执行的操作在某种程度上是不允许的

在C,当我们在B完成工作并离开let作用域后,B窗口对象将被取消引用并被垃圾收集。但我想向底层窗口机制发出信号,它现在应该回滚B更改,并再次接受范围活动。因此,在C处的作用就好像B效应没有发生一样

同样,如果顶级A窗口不再被引用,它应该在垃圾收集之前以任何方式自毁

我可以通过让window修改注册窗口引用的全局状态来管理这一点,但我不确定如何检测B范围引用丢失的点。如何检查对一段数据的引用?还是有其他方法来解决这个问题


我意识到这是一个有点复杂的设置,但我想找到一种方法来协调gui编程的状态,并使其看起来尽可能纯净。

这不是构建正确程序的方法,当然,它不会像你希望的那样瞬间运行,以便根据它做出UI决策


从您的问题描述中根本不清楚您实际想要做什么,但将其与垃圾收集联系起来肯定是错误的做法。也许您可以在离开
B
后添加一些代码,这些代码将执行您想要的任何操作。

(让[窗口(使窗口宽度高度)](让[不同的窗口(调整窗口新宽度新高度)](更多操作窗口))
@delnan这与OP的现有代码没有任何有意义的区别。编译器不关心两个不同的变量是否具有相同的文本名称;他的示例中的两个
窗口
变量与您的一样独立。@amalloy我们中的一个需要仔细阅读。我的理解是:
调整大小
对窗口对象进行变异,但OP希望保持纯洁的假象,因此对唯一的其他绑定(应该是指不可变对象)进行阴影处理。我的代码片段没有阴影,因此可以使用外部引用,从而使用非常普通、有效的代码暴露变异。我也可以使用更复杂的示例,使用集合中的别名等,但我选择严格遵守OP的代码结构。@delnan您关心的问题并不是无效的,但我对这种情况的计划是当不同的窗口处于“活动”状态时,窗口上的操作在某种程度上是“无效”的。我认为瞬态可以做到这一点,所以我可能会使用类似的机制。你是对的,我不应该特别依赖垃圾收集器。我想要的是在对var或类似变量的“引用”数量减少时执行操作(在let/binding作用域的末尾)。我实际上想做的是对gui应用程序的可变状态进行建模,就好像它的可变程度较低一样,并且仅在创建和“销毁”不可变包装器时才对其应用更改.destroyed并不意味着垃圾已收集,它只需要意味着它的作用域已被保留,不再被引用。