我很擅长使用CLOS。在这里,我写了一种使用CLOS定义队列的可能方法:
(defclass Queue ()
((queue-size
:reader queue-size
:initarg :queue-size
:initform (error "Provide a queue-size when initialising a Queue")
:type number)
(elements
:accessor elements
:initform (make-array queue-size :initial-element nil))
(put-ptr
:accessor put-ptr
:initform 0
:type number)
(get-ptr
:accessor get-ptr
:initform 0
:type number)))
如您所见,我使用插槽queue-size
的值在插槽elements
中创建数组。但是,不幸的是,这给了我以下错误:
*** - DEFAULT-ELEMENTS: variable QUEUE-SIZE has no value
正如我所说,我对CLOS很陌生。有什么办法我还能这样做吗?是否可以覆盖某种init方法?如果是,我该怎么做?
答案 0 :(得分:7)
在CLOS中,您无法直接将插槽称为变量。此外,您无法在 initforms 中引用该对象的其他插槽。
示例,简化:
CL-USER 27 > (defclass queue () (size elements))
#<STANDARD-CLASS QUEUE 4020001AB3>
CL-USER 28 > (describe (make-instance 'queue))
#<QUEUE 40200040CB> is a QUEUE
SIZE #<unbound slot>
ELEMENTS #<unbound slot>
我们现在设置elements
广告位:
CL-USER 36 > (defclass queue () ((size :initarg :size) elements))
#<STANDARD-CLASS QUEUE 42E0A2DBFB>
为此,我们编写了initialize-instance
:after
方法。
通常的初始化发生在&em>之后我们的方法运行。 WITH-SLOTS
允许我们在代码中使用某些插槽,如变量。我们在这里访问广告位size
和elements
:
CL-USER 37 > (defmethod initialize-instance :after ((q queue) &rest initargs)
(with-slots (size elements) q
(setf elements (make-array size :initial-element nil))))
#<STANDARD-METHOD INITIALIZE-INSTANCE (:AFTER) (QUEUE) 402000ADD3>
没有宏 WITH-SLOTS
,使用功能 SLOT-VALUE
,它看起来像这样:
CL-USER 38 > (defmethod initialize-instance :after ((q queue) &rest initargs)
(setf (slot-value q 'elements)
(make-array (slot-value q 'size) :initial-element nil)))
示例:
CL-USER 39 > (describe (make-instance 'queue :size 10))
#<QUEUE 402000BE0B> is a QUEUE
SIZE 10
ELEMENTS #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)