【问题标题】:CLOS: Use a slot value to initialize another slotCLOS:使用一个槽值来初始化另一个槽
【发布时间】:2015-11-09 08:41:21
【问题描述】:

我对使用 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 很陌生。有什么办法我仍然可以做到这一点?是否可以覆盖某种初始化方法?如果是,我该怎么做?

【问题讨论】:

    标签: lisp common-lisp clos


    【解决方案1】:

    在 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 方法。 通常的初始化发生在我们的方法运行之后WITH-SLOTS 允许我们在代码中使用某些插槽,例如变量。在这里我们访问插槽sizeelements

    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)
    

    【讨论】:

    • 这正是我所需要的。另外,我学到了一些关于 CLOS 的新知识。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-06-04
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多