6

任何 CL'er 可以解释一下 CLOS 中的“插槽”吗?我发现很难理解插槽名称后面的部分。那是在:

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

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

谢谢!

4

2 回答 2

8

你的例子有点错误。它一定要是:

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

请注意添加的括号以指示插槽描述列表。

DEFCLASS 采用插槽列表。因此,我们有两个插槽:

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

DATA1 是插槽的名称。在这之后你会发现成对的 :keyword 值。

: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 介绍

于 2009-03-10T12:21:35.617 回答
1

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

:reader读取槽值的函数
:writer写入槽值的函数
:accessor读取和(通过 SETF)设置槽值的函数
:initarg设置槽值的符号制作实例

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

于 2009-03-10T11:35:04.120 回答