Lisp.槽属性(Slot Properties)

defclass的第三个参数必须是一个槽定义的列表。最简单的槽定义,就像前一篇文章所看到的,就是一个标识名字的符号(symbol)。通常情况下,一个槽可以定义为一个列表,这个列表是由名字,和它所带有的一个或多个属性组成。属性以关键字参数的形式给出。


通过定义一个槽的 :accessor ,我们就隐式地创建了一个引用那个槽的函数,这样就无需调用slot-value了。如果我们把circle类的定义更新成如下:

[1]> 
(defclass circle ()
  ((radius :accessor circle-radius)
   (center :accessor circle-center)))
#<STANDARD-CLASS CIRCLE>

然后我们就可以通过circle-radius和circle-center来引用槽了:

[2]> 
(setf c (make-instance 'circle))
#<CIRCLE #x00033540CE78>
[3]> (setf (circle-radius c) 1)
1
[4]> (circle-radius c)
1

当然我们也还可以通过通用的方式来引用:

[7]> (setf (slot-value c 'radius) 100)
100
[8]> (circle-radius c)                
100
通过指定一个:writer或者一个:reader,而不是:accessor,我们可以分别获得这个行为的前后部分。


要设定一个槽的默认值,我们需要给出一个:initform参数。如果我们想能够在调用make-instance的时候初始化槽,我们需要定义一个:initarg参数。当两个都加上的时候,我们的类定义就变成了:

[1]> (defclass circle ()
  ((radius :accessor circle-radius
           :initarg :radius
           :initform 1)
   (center :accessor circle-center
           :initarg :center
           :initform (cons 0 0))))
#<STANDARD-CLASS CIRCLE>


现在,当我们创建一个circle的实例的时候,我们既可以使用:initarg定义的关键字参数传递一个值,也可以使用:initform为槽设定的默认值。

[2]> (setf c (make-instance 'circle :radius 3))
#<CIRCLE #x00033E435198>
[3]> (circle-radius c)
3
[4]> (circle-center c)
(0 . 0)

注意,:initarg的优先级要高于:initform。


我们也可以指定某些槽是被共享的(静态变量-译者注)——也就是说,它们的值对于每个实例都是一样的。我们通过给这个槽指定:allocation :class来达到这个目的。(另一个可选的项是:allocation :instance,这是默认值,也就没有必要显式地写出来了)当我们在一个实例中改变这个槽的值的时候,其它每个实例也会得到改变后的相同的值。所以,我们通过使用共享槽来存储所有的实例公用的属性。


比如,假设我们想要模拟一群小报的行为。在我们的模拟中,我们希望能够模拟这样的事实:当一个小报获得一个主题后,它们都会获得。我们可以通过让所有的实例共享一个槽来达成目的。如果tabloid类被定义成如下:

[5]> (defclass tabloid ()
  ((top-story :accessor tabloid-story
              :allocation :class)))
#<STANDARD-CLASS TABLOID>

然后,我们创建tabloid的两个实例,不论什么变成了其中一个的首页新闻,也会变成其它的首页新闻:

[7]> (setf (tabloid-story daily-blab) 'adult-of-senator)
ADULT-OF-SENATOR
[8]> (tabloid-story unsolicited-mail)
ADULT-OF-SENATOR

如果:document属性被给出的话,它的值应该是作为描述这个槽的文档字符串。通过指定:type,可以保证那个槽只包含那种类型的元素。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值