sbcl/CLOS为什么我必须在这里添加"validate-superclass"-Method?

Pat*_*ick 2 common-lisp clos mop

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

CL-USER> (defclass counting-class (standard-class)
   ((counter :initform 0)))
#<STANDARD-CLASS COUNTING-CLASS>
Run Code Online (Sandbox Code Playgroud)

并向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}>
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

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

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}>
Run Code Online (Sandbox Code Playgroud)

有用:

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

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

从我的POV开始,将计数类声明为标准类的衍生物就足够了,正如我在第一步中所做的那样.

sds*_*sds 9

validate-superclass的CLOS MOP规范说默认方法t只返回微不足道的情况并添加:

定义方法validate-superclass需要详细了解内部协议,然后是两个类元对象类中的每一个.validate-superclass对两个不同的类元对象类返回true的方法声明它们是兼容的.

你可以认为你validate-superclass是一个宣言,你明白你在做什么.

顺便说一下,我认为你可以定义一个更容易计算其实例的类.

PS.某些实现也会t在其他一些情况下返回.

  • 重点是理解元类,而不是创建一个类来计算实例。计数类是 AMOP 中给出的元类的第一个示例。 (2认同)