而结构可以想成是,这些函数通通都替你定义好了的向量。
要想定义结构,使用 defstruct
。在最简单的情况下,只要给出结构及字段的名字便可以了:
(defstruct point
x
y)
这里定义了一个 point
结构,具有两个字段 x
与 y
。同时隐式地定义了 make-point
、 point-p
、 copy-point
、 point-x
及 point-y
函数。
每一个 make-point
的调用,会返回一个新的 point
。可以通过给予对应的关键字参数,来指定单一字段的值:
#S(POINT X 0 Y 0)
存取 point
字段的函数不仅被定义成可取出数值,也可以搭配 setf
一起使用。
定义结构也定义了以结构为名的类型。每个点的类型层级会是,类型 point
,接着是类型 structure
,再来是类型 atom
,最后是 t
类型。所以使用 point-p
来测试某个东西是不是一个点时,也可以使用通用性的函数,像是 typep
来测试。
> (point-p p)
T
T
(defstruct polemic
(type (progn
(format t "What kind of polemic was it? ")
(effect nil))
如果 make-polemic
调用没有给字段指定初始值,则字段会被设成缺省表达式的值:
结构显示的方式也可以控制,以及结构自动产生的存取函数的字首。以下是做了前述两件事的 point
定义:
(defstruct (point (:conc-name p)
(x 0)
(y 0))
(defun print-point (p stream depth)
(format stream "#<~A, ~A>" (px p) (py p)))
:conc-name
关键字参数指定了要放在字段前面的名字,并用这个名字来生成存取函数。预设是 point-
;现在变成只有 p
。不使用缺省的方式使代码的可读性些微降低了,只有在需要常常用到这些存取函数时,你才会想取个短点的名字。
函数 print-point
会用缩写的形式来显示点:
#<0,0>