在 Python 中,我会这样做:
class foo:
def __init__(self):
self.x = self
否则,现在对象是它自己的参数。我怎样才能用普通的 lisp 做到这一点?
(defclass mn ()
((pai :accessor mn-pai
:initarg :pai
:initform self)))
最佳答案
在 DEFCLASS
槽描述 中,不能引用对象本身。但是可以编写实例初始化 的方法。这类似于您的 Python 示例。
我们类(class):
? (defclass foo ()
((bar :accessor foo-bar :initarg :foo)))
#<STANDARD-CLASS FOO>
我们为initialize-instance
创建了一个:after
方法。这个通用函数由 CLOS 提供,其目的是初始化一个新实例。第一个参数是要初始化的实例。当我们创建 foo
类的实例时,Lisp 系统将调用该方法。
使用访问器(accessor)foo-bar
:
? (defmethod initialize-instance :after ((object foo) &key)
(setf (foo-bar object) object))
#<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
或通过(setf slot-value)
设置插槽。
? (defmethod initialize-instance :after ((object foo) &key)
(setf (slot-value object 'bar) object))
#<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
请注意,我们可以用任何名称命名实例参数:object
甚至 self
。但是名称没有语义。由于在 CLOS 中我们有多重调度(调度可以处理多个参数并且没有默认调度参数),所以没有 self
语义。
现在我们创建并描述类 foo
的实例:
? (describe (make-instance 'foo))
#<FOO #x302000D20C0D>
Class: #<STANDARD-CLASS FOO>
Wrapper: #<CCL::CLASS-WRAPPER FOO #x302000D2B43D>
Instance slots
BAR: #<FOO #x302000D20C0D>
如您所见,该实例的插槽 bar
已设置为实例本身。
关于oop - 对象作为 lisp 中自身的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50826649/