"overriding" :超类的 defclass 中的 initform 设置 (CLOS)
"overriding" :initform setting in defclass for superclass (CLOS)
我有一个用 :initform
定义的 class
(defclass A()
((MI :initarg :mi :initform (error "must specify mi") ) ) )
它带有一个初始化实例 :after 方法来计算一些东西(太长而无法显示);该计算的最终结果与 class A 和派生的 class B 相关;见下文)
和派生的 class
(defclass B(A)
(( ABC :initarg :abc :initform (error "must specify abc") ) ) )
现在,class B 需要在其各自的初始化实例方法中执行与 A 相同的计算;但是,在这种情况下,A 中的参数 mi 是 B 中 ABC 的函数。
所以我尝试在 B 的初始化实例中计算一个 "temporary mi";没用
我尝试计算 mi,将其存储在 B 的 ABC 的局部变量 mitmp 中并调用 (call-next-method mitmp);没用
我试图在 B 中定义另一个 MI 字段,而不像在 A 中那样使用 :initform。我希望我能够在 B 的初始化实例中的 let-form 中计算 mi;也没用。
[使用像 C++ 这样的 Blub 语言,这就可以了;不知何故,我一直坚持这种思维方式。]
所以我剩下的问题是 "how can I have B to have a mandatory argument ABC that than is "transformed" 变成强制性的 A 的 mi 并赋予 A 的初始化实例。
欢迎任何提示。
[编辑:澄清了一些事情]
您可以在 b
上定义一个 :before
方法 initialize-instance
。如果您使用 :after
方法,它只会在 a
已经初始化后获得 运行。一个简单的例子:
(defclass a ()
((mi :initarg :mi :initform (error "Must specify mi"))
(computed-value :accessor computed-value)))
(defmethod initialize-instance :after ((a a) &key)
(with-slots (mi computed-value) a
(setf computed-value (* mi 2))))
(defclass b (a)
((abc :initarg :abc :initform (error "must specify abc"))))
(defmethod initialize-instance :before ((b b) &key (abc 1 abc-p))
;; You have to check that ABC was given manually, since this is
;; run before initialising B. You wouldn't necessarily even
;; need to have a slot for ABC if you don't need it for anything
;; else.
(unless abc-p (error "Must specify abc"))
(setf (slot-value b 'mi) (+ abc 10)))
(computed-value (make-instance 'a :mi 4))
; => 8
(computed-value (make-instance 'b :abc 4))
; => 28
我有一个用 :initform
定义的 class(defclass A()
((MI :initarg :mi :initform (error "must specify mi") ) ) )
它带有一个初始化实例 :after 方法来计算一些东西(太长而无法显示);该计算的最终结果与 class A 和派生的 class B 相关;见下文)
和派生的 class
(defclass B(A)
(( ABC :initarg :abc :initform (error "must specify abc") ) ) )
现在,class B 需要在其各自的初始化实例方法中执行与 A 相同的计算;但是,在这种情况下,A 中的参数 mi 是 B 中 ABC 的函数。
所以我尝试在 B 的初始化实例中计算一个 "temporary mi";没用
我尝试计算 mi,将其存储在 B 的 ABC 的局部变量 mitmp 中并调用 (call-next-method mitmp);没用
我试图在 B 中定义另一个 MI 字段,而不像在 A 中那样使用 :initform。我希望我能够在 B 的初始化实例中的 let-form 中计算 mi;也没用。
[使用像 C++ 这样的 Blub 语言,这就可以了;不知何故,我一直坚持这种思维方式。]
所以我剩下的问题是 "how can I have B to have a mandatory argument ABC that than is "transformed" 变成强制性的 A 的 mi 并赋予 A 的初始化实例。
欢迎任何提示。
[编辑:澄清了一些事情]
您可以在 b
上定义一个 :before
方法 initialize-instance
。如果您使用 :after
方法,它只会在 a
已经初始化后获得 运行。一个简单的例子:
(defclass a ()
((mi :initarg :mi :initform (error "Must specify mi"))
(computed-value :accessor computed-value)))
(defmethod initialize-instance :after ((a a) &key)
(with-slots (mi computed-value) a
(setf computed-value (* mi 2))))
(defclass b (a)
((abc :initarg :abc :initform (error "must specify abc"))))
(defmethod initialize-instance :before ((b b) &key (abc 1 abc-p))
;; You have to check that ABC was given manually, since this is
;; run before initialising B. You wouldn't necessarily even
;; need to have a slot for ABC if you don't need it for anything
;; else.
(unless abc-p (error "Must specify abc"))
(setf (slot-value b 'mi) (+ abc 10)))
(computed-value (make-instance 'a :mi 4))
; => 8
(computed-value (make-instance 'b :abc 4))
; => 28