如何将实例“投射”到子类?

Arn*_*aud 3 common-lisp clos

我有一个类消息的实例,我将其称为“ msg”。我已经定义了一个类“ my-message”,并且希望实例“ msg”现在属于该类。

在我看来,它应该相对简单,但我不知道该怎么做。更改类给我一个我不明白的错误。

(defclass my-message (message)
  ((account-name :accessor account-name :initform nil :initarg :account-name)))

(change-class msg 'my-message :account-name account-name)

ERROR :
While computing the class precedence list of the class named MW::MY-MESSAGE.
The class named MW::MESSAGE is a forward referenced class.
The class named MW::MESSAGE is a direct superclass of the class named MW::MY-MESSAGE.
Run Code Online (Sandbox Code Playgroud)

cor*_*ump 5

The class named MW::MESSAGE is a forward referenced class.
Run Code Online (Sandbox Code Playgroud)

前向引用的类是您引用但尚未定义的类。如果您查看类的名称,则为MW::MESSAGE。我想您想继承另一个MESSAGE在另一个包中命名的类;您导入的符号可能有问题。

The class named MW::MESSAGE is a direct superclass of the class named MW::MY-MESSAGE.
Run Code Online (Sandbox Code Playgroud)

由于MW::MESSAGE尚未定义该类,因此无法创建它的实例。这也是为什么您无法为其任何子类创建实例的原因MW::MY-MESSAGE


Rai*_*wig 5

这对我有用:

CL-USER>  (defclass message () ())
#<STANDARD-CLASS COMMON-LISP-USER::MESSAGE>

CL-USER> (defparameter *msg* (make-instance 'message))
*MSG*

CL-USER> (describe *msg*)
#<MESSAGE {1002FE43F3}>
  [standard-object]
No slots.


CL-USER> (defclass my-message (message)
           ((account-name :accessor account-name
                          :initform nil
                          :initarg :account-name)))
#<STANDARD-CLASS COMMON-LISP-USER::MY-MESSAGE>

CL-USER> (change-class *msg* 'my-message  :account-name "foo")
#<MY-MESSAGE {1002FE43F3}>

CL-USER> (describe *msg*)
#<MY-MESSAGE {1002FE43F3}>
  [standard-object]

Slots with :INSTANCE allocation:
  ACCOUNT-NAME  = "foo"
Run Code Online (Sandbox Code Playgroud)

请注意,这不是强制转换,因为对象本身将被更改。它现在是不同类的实例。转换通常意味着在某些情况下,只是对未改变事物的解释发生了变化。但这里的情况确实发生了变化,旧的解释不再适用。