mob*_*eng 9 sbcl common-lisp clos
这种情况一次又一次地发生在我身上:我定义了这个类并忘记了我想要它的功能,或者它是,例如,Gtk小部件类,因此它的元类需要说明.一旦它被定义,但是,SBCL不会让我改变了我的元类(即使没有这个类的实例).例如,评估
(defclass foo ()
((slot-a)))
Run Code Online (Sandbox Code Playgroud)
然后添加元类并重新评估:
(defclass foo ()
((slot-a))
(:metaclass gobject:gobject-class))
Run Code Online (Sandbox Code Playgroud)
导致错误:
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]
Run Code Online (Sandbox Code Playgroud)
不幸的是,我没有"元对象协议的艺术"的副本来检查它的内容.现在我唯一可以解决的方法是重启lisp,这可能会造成很大的破坏性.
由于我很快意识到错误,我不介意通过删除它完全避开已定义的类.问题:
fmakunbound
功能一样的东西.cor*_*ump 10
不幸的是,我没有"元对象协议的艺术"的副本来检查它的内容.
即使我推荐阅读这本书,你也可以在网上找到一些信息.例如,参见ENSURE-CLASS-USING-CLASS
.
如何删除课程?
你可以使用(SETF FIND-CLASS)
:
(setf (find-class 'foo) nil)
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用花式粘液检查员.slime-inspect-defintion
在指向类的名称时调用.然后,你会看到名字.选择它时,检查命名类的符号.然后,你可以看到类似的东西:
It names the class FOO [remove]
Run Code Online (Sandbox Code Playgroud)
如果FOO只命名一个类,你可以使用更大的锤子:
(unintern 'foo)
Run Code Online (Sandbox Code Playgroud)
如果我已经创建了类的实例,有没有办法找到它们来使它们无效并让它们获得GCed?
不,只有GC具有全局视图,并且出于实际原因,它通常不会向后引用关于谁引用特定对象(以及如何)1.除非您引入自己的(弱)哈希表来存储它们,否则没有类的所有实例的全局记录.但是如果你保留了所有实例的记录,那么就可以CHANGE-CLASS
了.例如,您定义:
(defclass garbage () ())
Run Code Online (Sandbox Code Playgroud)
...将释放您对象中以前保存的任何引用,并且GC有机会处理引用的实例对象.当另一个对象引用'garbage的实例时,你可以更新它.而不是使用"的垃圾,你或许可以改变旧的类的实例,以新类(名字是一样的,但类对象是不同的).另请注意,这CHANGE-CLASS
是一个通用函数.
1.实现可能会提供堆步行者.例如,参见Allegro CL中的Heap walker.
归档时间: |
|
查看次数: |
452 次 |
最近记录: |