有克隆CLOS对象的通用方法吗? [英] Is there a generic method for cloning CLOS objects?

查看:96
本文介绍了有克隆CLOS对象的通用方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种浅层克隆CLOS对象的方法,因此创建的对象将是同一类型,每个插槽中的值相同,但是是一个新实例。我发现最接近的是标准函数copy-structure,它对结构执行此操作。

I'm looking for a way to clone CLOS objects in a shallow manner, so the created object would be of the same type with the same values in each slot, but a new instance. The closest thing I found is a standard function copy-structure which does this for structures.

推荐答案

没有标准的预定义方法可以通常复制CLOS对象。如果有可能,提供合理的默认复制操作并不是一件容易的事,因为它的正确语义在不同的类之间以及在不同的应用程序之间变化,因此至少在大多数情况下大部分时间都对任意对象执行正确的操作。 MOP提供的扩展可能性使提供这样的默认值变得更加困难。另外,在CL中,作为一种垃圾收集语言,实际上并不需要经常复制对象,例如,作为参数传递或返回时。因此,根据需要实施复制操作可能是最干净的解决方案。

There is no standard predefined way to copy CLOS objects in general. It is not trivial, if possible at all, to provide a reasonable default copy operation that does the right thing (at least) most of the time for arbitrary objects, since the correct semantics change from class to class and from application to application. The extended possibilities the MOP provides make it even harder to provide such a default. Also, in CL, being a garbage collected language, copying of objects is not really needed very often, e.g. when passed as parameters or being returned. So, implementing your copy operations as needed would probably be the cleanest solution.

话虽这么说,这就是我在其中一个片段文件中发现的,这可能会做些什么您想

That being said, here is what I found in one of my snippet files, which might do what you want:

(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支持-definition-name

(我可能是从一个旧的cll线程,但我不记得了。我从来没有真正需要过这样的东西,因此未经测试。)

(I probably adopted this from an old c.l.l thread, but I can't remember. I never really needed something like this, so it's utterly untested.)

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

You can use it like this (tested with 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>

这篇关于有克隆CLOS对象的通用方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆