任何 CL'er 可以解释一下 CLOS 中的“插槽”吗?我发现很难理解插槽名称后面的部分。那是在:
(defclass foo () (data1 :initarg foo))
“initarg”和其他类似的东西是什么意思?我正在重新阅读手册。所以,如果你们中的任何人能向像我这样的外行解释一下,我将不胜感激。
谢谢!
任何 CL'er 可以解释一下 CLOS 中的“插槽”吗?我发现很难理解插槽名称后面的部分。那是在:
(defclass foo () (data1 :initarg foo))
“initarg”和其他类似的东西是什么意思?我正在重新阅读手册。所以,如果你们中的任何人能向像我这样的外行解释一下,我将不胜感激。
谢谢!
你的例子有点错误。它一定要是:
(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 介绍。
在插槽规范中,一般语法是 ( slot-name [ slot-option option-value ]...)。本质上的权威参考是defclass 上的 HyperSpec 页面,但简而言之:
:reader读取槽值的函数
:writer写入槽值的函数
:accessor读取和(通过 SETF)设置槽值的函数
:initarg设置槽值的符号制作实例
还有更多,但该列表是我最常用的四个(实际上,我主要使用 :initarg 和 :accessor 或 :reader 之一)。