8
votes

Y a-t-il une méthode générique pour cloner des objets rapprochés?

Je recherche un moyen de cloner des objets de fermeture de manière peu profonde, l'objet créé serait du même type avec les mêmes valeurs dans chaque fente, mais une nouvelle instance. La chose la plus proche que j'ai trouvée est une structure de copie de fonction standard qui fait cela pour les structures.


0 commentaires

4 Réponses :


12
votes

Il n'y a pas de moyen prédéfini standard de copier des objets rapprochés en général. Il n'est pas trivial, si possible du tout, de fournir une opération de copie par défaut raisonnable qui fait la bonne chose (au moins) la plupart du temps pour les objets arbitraires, car la sémantique correcte change de la classe en classe et de l'application à l'application. Les possibilités étendues que la vadrouille fournit le rendement plus difficile à fournir une telle défaillance. De plus, en CL, étant une langue collectée des ordures, la copie d'objets n'est pas vraiment nécessaire très souvent, par ex. lorsqu'il est passé en tant que paramètres ou être retourné. Donc, la mise en œuvre de vos opérations de copie si nécessaire serait probablement la solution la plus propre.

QU'être dit, voici ce que j'ai trouvé dans l'un de mes fichiers d'extraits, ce qui pourrait faire ce que vous voulez: p> xxx

Vous aurez besoin d'une prise en charge de la MOP pour Slots de classe code> et nom de définition d'emplacement code>. p>

(J'ai probablement adopté cela de Un vieux fil CLL , mais je peux ' t Se souvenir. Je n'ai jamais eu vraiment besoin de quelque chose comme ça, il est donc totalement non testé.) p>

Vous pouvez l'utiliser comme ceci (testé avec CCL): P>

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>


2 commentaires

Il peut être utile d'ajouter un test si une fente est liée ou non. Ensuite, accédez uniquement à la valeur de l'emplacement uniquement si la fente est liée.


Fonctionne comme annoncé. Voici une déclaration d'importation qui devrait le faire fonctionner de manière plus portable plus ou moins: (: ombrage-import-de # + OpenMCl-natif-threads #: CCL # + CMU #: PCL # + SBCL #: SB-PCL # + LISPWORKS #: HCL # + Allegro #: MOP # + Clisp #: Clos #: Class-Slots #: Slot-définition-nom) .



8
votes

Voici une version légèrement différente de la fonction soumise par Danlei. J'ai écrit cela il y a un moment et je suis tombé sur ce poteau. Pour des raisons que je ne me souviens pas entièrement, cela appelle à la réinitialisation-instance après la copie. Je pense C'est ainsi que vous pouvez modifier le nouvel objet en passant des injustars supplémentaires à cette fonction

par exemple xxx

ceci est également défini. comme fonction générique sur des objets «d'objet standard». Qui pourrait ou pourrait ne pas être la bonne chose à faire. xxx


1 commentaires

Exactement ce que je cherchais; J'ai été surpris que cela n'existe pas par défaut dans les Lisp communs.



0
votes

Cette solution ne nécessite pas sl-wob : xxx


0 commentaires

-1
votes

Je mentionne une astuce sale produisant un clone d'une instance de fermeture. XXX

implique de clôture elle-même nécessite une notion de clone.


0 commentaires