【发布时间】:2017-02-12 12:15:39
【问题描述】:
我需要在运行时创建一个类,可能不使用 eval。知道Common-Lisp中元类协议没有完全标准化,浏览了The Common Lisp Object System MetaObject Protocol之后,我尝试了下面的代码来创建一个类,实例化它,并将实例的一个槽值设置为一个数字:
(defparameter *my-class*
(make-instance 'standard-class
:name 'my-class
:direct-slots '((:name x :readers (get-x) :writers ((setf get-x))))))
(defparameter *my-instance* (make-instance *my-class*))
(setf (get-x *my-instance*) 42) ;; => 42
不幸的是,这段代码在 SBCL 上正常工作,但在 CCL 上却不能正常工作,在 CCL 上,类创建似乎工作,但实例创建 (make-instance *my-class*) 导致以下错误:
There is no applicable method for the generic function:
#<STANDARD-GENERIC-FUNCTION INITIALIZE-INSTANCE #x30200002481F>
when called with arguments:
(#<error printing CONS #x302001A9F6A3>
[Condition of type CCL:NO-APPLICABLE-METHOD-EXISTS]
我尝试查看 closer-mop 包,它应该隐藏元对象协议的各种实现之间的差异,但我找不到任何对我的范围有用的函数或类。
所以问题是:有没有一种可移植的方式来创建一个类并在运行时通过直接使用 CLOS 的元类级别来实例化它?
【问题讨论】:
-
使用更紧密的拖把,您可以尝试ensure-class 或ensure-class-using-class。
-
如果您也指定直接超类,CCL 似乎也可以工作
:direct-superclasses (list (find-class 'standard-object)) -
谢谢@jkiiski,问题是我应该指定超类。如果您将其发布为答案,我会接受。
-
谢谢,@coredump,实际上
ensure-class不适用于我的参数,但如果我添加直接超类standard-object则可以正常工作(我以为这是默认设置,但也许这是仅适用于defclass)。 -
哦,因为 B->C 确实没有保存。
标签: common-lisp sbcl clos ccl