Lisp.结构(Structure)

一个结构(structure)可以看成是一个加强版的向量(vector)。假设你需要写一个程序来跟踪许多长方体。你可能会考虑将它们表示成一个具有三个元素的向量:高,宽和长。如果你使用诸如如下的函数,而不是使用原始的svrefs,将使你的程序更加易读:

[1]> (defun block-height (b) (svref b 0))
BLOCK-HEIGHT

你可以将一个结构看成是一个特殊的向量,类似于以上的这种函数都给你定义好了。


要定义一个结构,我们要使用defstructure。最简单的情况下,我们只给出结构的名字和和字段:

[3]> (defstruct point x y)
POINT

这把一个“点”定义成一个结构,这个结构有两个字段,x和y。它也隐式地定义了如下函数:make-point, point-p, copy-point,point-x和point-y。我们曾经提到过Lisp程序可以写Lisp程序。这是到目前为止我们看到的最显著的例子了。当你调用defstructure的时候,它自动地书写了定义其它几个函数的代码。利用宏你可以做到同样的事情。(如果需要,你甚至可以自己版本的defstructure)


对make-point的调用会返回一个新的点。我可以通过给出相应的关键字参数来设定单独的字段:

[2]> (setf p (make-point :x 0 :y 0))
#S(POINT :X 0 :Y 0)
“点”的字段访问函数不仅仅能用来取值,也是可以和setf来共同工作的。

[3]> (point-x p)
0
[4]> (setf (point-y p) 2)
2
[5]> p
#S(POINT :X 0 :Y 2)

定义一个结构也同时定义了一个相同名字的类型(type)。每个点都是“点”(point)类型,然后是结构(structure),然后是原子(atom),然后是t。同样我们使用point-p来判断一个东西是不是一个“点”,当然我们也可以使用通用的函数,像是typep。

[11]> (point-p p)     
T
[12]> (typep p 'point)
T
我们可以为结构的字段设定默认值,方法就是在原始定义中将字段名和一个默认表值达式。

[1]> (defstruct polemic
  (type (progn
          (format t "What kind of polemic was it ?")
          (read)))
  (effect nil))
POLEMIC
[2]> (make-polemic :effect "good")
What kind of polemic was it ?8
#S(POLEMIC :TYPE 8 :EFFECT "good")
[5]> (make-polemic)             
What kind of polemic was it ?8
#S(POLEMIC :TYPE 8 :EFFECT NIL)
如果对make-polemic的调用没有指定这些字段的默认值,它们会被设定成对应的表达式。


我们也可以控制结构显示的方式,还有自动创建的访问函数的名字中使用的前缀。这里是做以上两件事情的一个详尽的定义:

[6]> (defstruct (point (:conc-name p) (:print-function print-point)) (x 0) (y 0))
POINT
[7]> (defun print-point (p stream depth) (format stream "#<~A, ~A>" (px p) (py p)))
PRINT-POINT

:conc-name参数指定了访问函数中加在字段名之前的前缀。默认是point-;现在成了简单的p了。不使用默认的前缀使得你的代码损失一些易读性,所以你只有在经常使用访问函数的时候才希望这样做。


:print-function是被用来在需要打印“点”的时候,使用的函数的名字——比如toplevel。这个函数必须接受3个参数:需要被打印的结构,打印到哪里,第三个参数通常忽略掉。我们将会在后面学习到streams。现在来说,知道stream可以简单地传递给format就足够了。


函数print-point将以简短的形式来打印点:

[8]> (make-point )
#<0, 0>





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值