gpt4 book ai didi

common-lisp - 如何更改类的元类

转载 作者:行者123 更新时间:2023-12-04 03:49:41 25 4
gpt4 key购买 nike

这种情况一次又一次地发生在我身上:我定义了类,却忘记了我希望它是可调用的,或者它是 Gtk 小部件类,因此需要说明它的元类。但是,一旦定义了它,SBCL 就不允许我更改元类(即使没有此类的实例)。例如,评估

(defclass foo ()
((slot-a)))

然后添加一个元类并重新评估:
(defclass foo ()
((slot-a))
(:metaclass gobject:gobject-class))

导致错误:
Cannot CHANGE-CLASS objects into CLASS metaobjects.
[Condition of type SB-PCL::METAOBJECT-INITIALIZATION-VIOLATION]
See also:
The Art of the Metaobject Protocol, CLASS [:initialization]

不幸的是,我没有《元对象协议(protocol)的艺术》的副本来检查它的内容。目前我能想到的唯一方法是重新启动 lisp,这可能会造成很大的破坏。

由于我很快意识到错误,我不介意通过删除它来完全避开定义的类。问题:
  • 如果我创建了该类的实例,有没有办法找到它们以使它们无效并让它们被 GCed?
  • 如何删除类?像 fmakunbound对于功能。
  • 最佳答案

    Unfortunately I don't have a copy of The Art of the Metaobject Protocol to check what it says.



    即使我推荐阅读这本书,你也可以在网上找到一些信息。参见示例 ENSURE-CLASS-USING-CLASS .

    How to remove the class?



    您可以使用 (SETF FIND-CLASS) :
    (setf (find-class 'foo) nil)

    或者,您可以使用花哨的粘液检查器。您调用 slime-inspect-defintion同时指向类的名称。然后,您将看到名称。当你选择它时,你检查命名你的类的符号。然后,您可以看到如下内容:
    It names the class FOO [remove]

    如果 FOO 只命名一个类,您可以使用更大的锤子:
    (unintern 'foo)

    If I have created instances of the class, is there a way to find them to nullify them and get them GCed?



    不,只有 GC 具有全局 View ,并且出于实际原因,它通常不会保留关于谁引用特定对象(以及如何引用)的向后引用 1 .
    除非您引入自己的(弱)哈希表来存储它们,否则没有类的所有实例的全局记录。但是,如果您保留了所有实例的记录,则可以 CHANGE-CLASS 他们。例如,您定义:
    (defclass garbage () ())

    ...您的对象中任何先前持有的引用都将被释放,并且 GC 有机会处理您的实例引用的对象。并且当另一个对象引用 'garbage 的实例时,您可以对其进行更新。您可以将旧类的实例更改为新类,而不是使用 'garbage(名称相同,但类对象不同)。
    另请注意 CHANGE-CLASS是一个通用函数。

    1 .实现可能会提供堆遍历器。参见示例 Heap walkers in Allegro CL .

    关于common-lisp - 如何更改类的元类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38811931/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com