sbcl / CLOS 为什么我必须在此处添加"validate-superclass" -方法?



在SBCL中,当我定义新的元类时

CL-USER> (defclass counting-class (standard-class)
   ((counter :initform 0)))
#<STANDARD-CLASS COUNTING-CLASS>

并在 GF "make-instance" 中添加一个方法:

CL-USER> (defmethod make-instance :after ((class counting-class) &key)
   (incf (slot-value class 'counter)))
#<STANDARD-METHOD MAKE-INSTANCE :AFTER (COUNTING-CLASS) {25302219}>

如果我尝试创建实例,则会收到错误:

CL-USER> (defclass counted-point () (x y) (:metaclass counting-class))
The class #<STANDARD-CLASS STANDARD-OBJECT> was specified as a
super-class of the class #<COUNTING-CLASS COUNTED-POINT>, but
the meta-classes #<STANDARD-CLASS STANDARD-CLASS> and
#<STANDARD-CLASS COUNTING-CLASS> are incompatible.  Define a
method for SB-MOP:VALIDATE-SUPERCLASS to avoid this error.

现在,如果我添加所需的定义:

CL-USER>  (defmethod sb-mop:validate-superclass ((class counting-class)
                                                 (super standard-class))
            t)
#<STANDARD-METHOD SB-MOP:VALIDATE-SUPERCLASS (COUNTING-CLASS STANDARD-CLASS) {26443EC9}>

它的工作原理:

CL-USER> (defclass counted-point () (x y) (:metaclass counting-class))
#<COUNTING-CLASS COUNTED-POINT>

我的问题是:为什么需要这样做?

从我的 POV 来看,将计数类声明为标准类的导数应该就足够了,就像我在第一步中所做的那样。

验证超类的 CLOS MOP 规范说默认方法仅在微不足道的情况下返回t并添加:

validate-superclass上定义方法需要详细的知识 内部协议后跟的两个类中的每一个 元对象类。validate-superclass上返回 true 的方法 对于两个不同的类元对象类声明它们是 相容。

你可以把你的validate-superclass看作是你明白自己在做什么的宣言。

顺便说一下,我认为您可以定义一个可以更轻松地计算其实例的类。

附言。在某些其他情况下,某些实现也会返回t

最新更新