是否有任何标准方法可以在 CLOS 中创建瞬态类;也就是说,一个在所有实例都死了之后可以被 GC 的类?
在 SBCL 中,我尝试(setf test (defclass #:foo () ()))
了,即在假设它通常只是导致该类被 GC 保留的类的名称的情况下使用 uninterned 符号,但在该类上安装 SBCL 终结函数,然后设置符号值从 TEST 到 NIL 表明,无论我运行多少次,该类都不会被 GC (gc :full t)
。这让我想知道这是否可能,如果可能,如何。
是否有任何标准方法可以在 CLOS 中创建瞬态类;也就是说,一个在所有实例都死了之后可以被 GC 的类?
在 SBCL 中,我尝试(setf test (defclass #:foo () ()))
了,即在假设它通常只是导致该类被 GC 保留的类的名称的情况下使用 uninterned 符号,但在该类上安装 SBCL 终结函数,然后设置符号值从 TEST 到 NIL 表明,无论我运行多少次,该类都不会被 GC (gc :full t)
。这让我想知道这是否可能,如果可能,如何。
类名(一个符号)没有被嵌入包中并不重要。FIND-CLASS
将通过查看一些内部注册表数据结构来找到该类。Clozure Common Lisp 使用例如一个普通的哈希表CCL::%FIND-CLASSES%
。
没有标准的方法。Common Lisp 标准没有提供任何机制。通常,CLOS 实现会希望提供某个类的所有子类的列表。为此,它需要一个类对其子类的引用。没有指定这应该是一个弱引用。例如 CLISP 将其实现为弱引用,其他 Common Lisp 实现可能不会。
解决方案草图:
因此,在终结器中,您需要调用REMOVE-DIRECT-SUBCLASS
(该函数可能在哪个包中,通常在 package 中CLOS
)以从其超类中删除该类。
您还需要调用(setf (find-class 'my-class-to-be-removed) nil)
.
您还最好看看该类本身没有子类。
因此,您可以使用广泛支持的 MOP 和特定于实现的终结器来构建一些东西。