是否有克隆CLOS对象泛型方法?(Is there a generic method for clo

2019-06-25 13:05发布

我正在寻找一种方式来克隆在浅方式CLOS的对象,所以创建的对象将是同一类型,在每个插槽相同的值,而是一个新的实例。 我发现的最接近的是一个标准的功能拷贝结构,做这行的结构。

Answer 1:

有一般的复制CLOS对象没有标准的预先定义的方式。 这是不平凡的,如果可能的话,要提供做正确的事合理的默认复制操作(至少)大部分时间任意对象,因为正确的语义,从类变为类和应用程序。 扩展的可能性MOP提供使它更难以提供这样的默认值。 此外,在CL,被垃圾回收的语言,对象的复制是不是真的时,作为参数传递或返回需要非常频繁,如。 因此,实现你的拷贝操作需要很可能是最干净的解决方案。

话虽这么说,这里是我在我的代码片段文件一经发现,这可能会做你想要什么:

(defun shallow-copy-object (original)
  (let* ((class (class-of original))
         (copy (allocate-instance class)))
    (dolist (slot (mapcar #'slot-definition-name (class-slots class)))
      (when (slot-boundp original slot)
        (setf (slot-value copy slot)
              (slot-value original slot))))
    copy))

您将需要一些MOP支持class-slotsslot-definition-name

(我可能是从采用了这种旧的CLL线程 ,但我不记得了。我从来没有真的需要这样的事情,所以这是完全未经测试)。

您可以使用它像这样(CCL测试):

CL-USER> (defclass foo ()
           ((x :accessor x :initarg :x)
            (y :accessor y :initarg :y)))
#<STANDARD-CLASS FOO>
CL-USER> (defmethod print-object ((obj foo) stream)
           (print-unreadable-object (obj stream :identity t :type t)
             (format stream ":x ~a :y ~a" (x obj) (y obj))))
#<STANDARD-METHOD PRINT-OBJECT (FOO T)>
CL-USER> (defparameter *f* (make-instance 'foo :x 1 :y 2))
*F*
CL-USER> *f*
#<FOO :x 1 :y 2 #xC7E5156>
CL-USER> (shallow-copy-object *f*)
#<FOO :x 1 :y 2 #xC850306>


Answer 2:

这里有一个稍微不同的版本提交danlei功能。 我前一段时间写了这一点,只是碰到这种职位绊倒了。 对于我并不完全召回原因为,该复印后要求重新初始化实例的。 我认为这是这样,你可以通过传递更多的initargs这个功能进行一些更改,新对象

(copy-instance *my-account* :balance 100.23)

这也被定义为通用的功能,而忽视了“标准对象的对象。 这可能是也可能不是做正确的事情。

(defgeneric copy-instance (object &rest initargs &key &allow-other-keys)
  (:documentation "Makes and returns a shallow copy of OBJECT.

  An uninitialized object of the same class as OBJECT is allocated by
  calling ALLOCATE-INSTANCE.  For all slots returned by
  CLASS-SLOTS, the returned object has the
  same slot values and slot-unbound status as OBJECT.

  REINITIALIZE-INSTANCE is called to update the copy with INITARGS.")
  (:method ((object standard-object) &rest initargs &key &allow-other-keys)
    (let* ((class (class-of object))
           (copy (allocate-instance class)))
      (dolist (slot-name (mapcar #'sb-mop:slot-definition-name (sb-mop:class-slots class)))
        (when (slot-boundp object slot-name)
          (setf (slot-value copy slot-name)
            (slot-value object slot-name))))
      (apply #'reinitialize-instance copy initargs))))


文章来源: Is there a generic method for cloning CLOS objects?