3

为什么我不能在 sbcl 中获得一个简单的类优先级列表?

* (sb-mop::class-precedence-list (find-class 'cons));;works

(#<BUILT-IN-CLASS CONS> #<BUILT-IN-CLASS LIST> #<SB-PCL:SYSTEM-CLASS SEQUENCE>
 #<SB-PCL:SYSTEM-CLASS T>)
* (defclass my-class ()    nil)
* (sb-mop::class-precedence-list (find-class 'my-class))

debugger invoked on a UNBOUND-SLOT in thread
#<THREAD "main thread" RUNNING {10039CE8D3}>:
  The slot SB-PCL::%CLASS-PRECEDENCE-LIST is unbound in the object
  #<STANDARD-CLASS MY-CLASS>.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [USE-VALUE  ] Return a value as the slot-value.
  1: [STORE-VALUE] Store and return a value as the slot-value.
  2: [ABORT      ] Exit debugger, returning to top level.

((:METHOD SLOT-UNBOUND (T T T)) #<unavailable argument> #<STANDARD-CLASS MY-CLASS> SB-PCL::%CLASS-PRECEDENCE-LIST) [fast-method]
0] 2
4

1 回答 1

4

类终结

从MOP描述:

类终结是计算类从其超类继承的信息并准备实际分配类实例的过程。类终结过程包括计算类的类优先级列表、类实例中可访问的完整插槽集以及类的完整默认初始化参数集。这些值与类元对象相关联,可以通过调用适当的阅读器来访问。此外,类终结过程决定如何实现类的实例。

为了支持前向引用的超类,并考虑到并非所有类都被实际实例化的事实,类终结不是作为类元对象初始化的一部分进行的。相反,终结是作为一个单独的协议完成的,通过调用通用函数 finalize-inheritance 来调用。调用 finalize-inheritance 的确切点取决于类元对象的类;对于标准类,在定义所有类超类之后的某个时间调用它,但不迟于分配类的第一个实例(通过 allocate-instance)。

类终结的第一步是计算类优先级列表。首先这样做允许后续步骤访问类优先级列表。此步骤通过调用通用函数 compute-class-precedence-list 来执行。此调用返回的值与类元对象相关联,可以通过调用 class-precedence-list 泛型函数来访问。

...

例子

* (defclass my-class () nil)

#<STANDARD-CLASS MY-CLASS>
* (sb-mop:class-finalized-p (find-class 'my-class))

NIL
* (sb-mop:finalize-inheritance (find-class 'my-class))

NIL
* (sb-mop:class-finalized-p (find-class 'my-class))

T
* (sb-mop:class-precedence-list (find-class 'my-class))

(#<STANDARD-CLASS MY-CLASS> #<STANDARD-CLASS STANDARD-OBJECT>
 #<SB-PCL::SLOT-CLASS SB-PCL::SLOT-OBJECT> #<SB-PCL:SYSTEM-CLASS T>)
于 2015-09-13T15:05:19.460 回答