如何"cast"一个实例到一个子类?
How to "cast" an instance to a subclass?
我有一个 class 消息的实例,我将调用 "msg"。我已经定义了一个 class "my-message" 并希望实例 "msg" 现在属于 class.
听起来应该比较简单,但我不知道该怎么做。 change-class 给我一个我不明白的错误。
(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.
The class named MW::MESSAGE is a forward referenced class.
前向引用 class 是您引用但尚未定义的 class。如果您查看 class 的名称,它是 MW::MESSAGE
。我想你想在另一个包中子 class 另一个名为 MESSAGE
的 class;您导入的符号可能有问题。
The class named MW::MESSAGE is a direct superclass of the class named MW::MY-MESSAGE.
由于 MW::MESSAGE
class 尚未定义,您无法创建它的实例。这也是为什么你不能创建它的任何子 class 实例的原因,例如 MW::MY-MESSAGE
.
这对我有用:
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"
请注意,这不是 cast,因为对象本身将被更改。它现在是另一个 class 的实例。 casting 通常意味着只是对未更改事物的解释在某些上下文中发生了变化。但是这里的实例真的变了,旧的解释不再适用。
我有一个 class 消息的实例,我将调用 "msg"。我已经定义了一个 class "my-message" 并希望实例 "msg" 现在属于 class.
听起来应该比较简单,但我不知道该怎么做。 change-class 给我一个我不明白的错误。
(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.
The class named MW::MESSAGE is a forward referenced class.
前向引用 class 是您引用但尚未定义的 class。如果您查看 class 的名称,它是 MW::MESSAGE
。我想你想在另一个包中子 class 另一个名为 MESSAGE
的 class;您导入的符号可能有问题。
The class named MW::MESSAGE is a direct superclass of the class named MW::MY-MESSAGE.
由于 MW::MESSAGE
class 尚未定义,您无法创建它的实例。这也是为什么你不能创建它的任何子 class 实例的原因,例如 MW::MY-MESSAGE
.
这对我有用:
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"
请注意,这不是 cast,因为对象本身将被更改。它现在是另一个 class 的实例。 casting 通常意味着只是对未更改事物的解释在某些上下文中发生了变化。但是这里的实例真的变了,旧的解释不再适用。