oop - 对象作为 lisp 中自身的参数

标签 oop lisp common-lisp clos object-initialization

在 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/

相关文章:

csv - 将 csv 文件读入列表列表的 Lisp 代码。

common-lisp - Allegro CL 中的 pprint

php - 如何在PHP中杀死页面

php - OO数据库类

compilation - 编译器的信号和错误之间的区别 (sbcl 1.2.4)

lisp - 是否有相当于 Common Lisp 在 Racket 中的插入?

python - 在 python 中查找实例的所有成员,不包括 __init__

c++ - 用 C++ 编写方法/函数的四种相同方法?

network-programming - 为什么IOLib中的 "receive-from"函数总是抛出EWOULDBLOCK异常?

macros - 宏扩展下特殊变量的行为