CLOS中的Slots

7

能否有CL的专家解释一下CLOS中的'slots'是什么?我很难理解slot名称后面的部分。就像这样:

(defclass foo () (data1 :initarg foo))

'initarg'和类似的其他东西代表什么意思?我正在重新阅读手册。所以,如果你们中的任何人能向我这样的门外汉解释一下,我将不胜感激。

谢谢!

2个回答

9

你的例子略有错误。正确的应该是:

(defclass foo ()
   ((data1 :initarg foo)))

注意添加的括号表示一个slot描述列表。

DEFCLASS接受一个slot列表。因此,如果有两个slots,则为:

(defclass foo ()
   ((data1 :initarg :data1arg
           :initform (random 1.0) 
           :type number
           :documentation "doc here"
           :accessor foo-data1-acc)
    (data2 :initarg :data2arg)))

DATA1是插槽的名称。在此之后,您会找到一对关键字值。

:INITARG告诉您MAKE-INSTANCE的参数。 (make-instance 'foo :data1arg 10) ; 创建对象并将插槽data1设置为10。 通常,您应该使用关键字符号(如:data1arg)。

:INITFORM在创建对象时默认设置插槽。例如: (make-instance 'foo) ; 创建对象。插槽被设置为initform的值。

:TYPE指定插槽对象的类型。

:DOCUMENTATION只是用于文档的字符串。

:ACCESSOR指定读取和写入插槽的函数。

(foo-data1-acc some-foo-object-here)             ; read
(setf (foo-data1-acc some-foo-object-here) 7)    ; write

请注意,您可以按任意顺序编写这些对,并且还可以指定多个访问器函数。还有:READER和:WRITER函数。
使用CLOS,您可以在DEFCLASS宏中指定所有这些内容。这些东西不像defstruct那样自动生成,后者具有更短的符号表示法。
DEFCLASS的描述在此处:DEFCLASS简短的CLOS介绍

在 :INITFORM 的描述中,slot data1 应该设置为 10 还是从 0 到 1.0 的随机值? - user59634
是的,那是一个错误。已在上面纠正。当未给出initarg时,将使用initform来初始化插槽。实际机制有点更复杂,但通常这已经足够了解。 - Rainer Joswig

1
在一个插槽规范中,一般的语法是 (slot-name [slot-option option-value]...)。权威参考资料是defclass的HyperSpec页面,简而言之:

:reader 读取插槽值的函数
:writer 写入插槽值的函数
:accessor 既可以读取也可以(通过SETF)设置插槽值的函数
:initarg 符号,用于从MAKE-INSTANCE设置插槽的值

还有更多,但这个列表是我最常用的四个(实际上,我主要使用:initarg和:accessor或:reader之一)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接