私は、浅い方法でCLOSオブジェクトをクローンする方法を探しています。そのため、作成されたオブジェクトは、各スロットに同じ値を持つ同じタイプのものになりますが、新しいインスタンスになります。私が見つけた最も近いものは、構造のためにこれを行う標準関数のコピー構造です。CLOSオブジェクトを複製する一般的な方法はありますか?
答えて
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))
あなたがclass-slots
とslot-definition-name
のためのいくつかのMOPのサポートが必要になります。
(私はおそらくan old c.l.l threadからこれを採用したが、私は、私は本当にこのような何かを必要としません思い出すことができないので、それは全くテストされていないのです。。)
あなたがこの(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>
ここでは、danleiによって提出された機能のわずかに異なるバージョンがあります。私はこれをしばらく前に書きましたが、このポストを偶然見つけました。私が完全に想起しない理由のために、これはコピー後にREINITIALIZE-INSTANCEを呼び出します。私はだと思います。この関数に追加の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))))
私が探していたものとまったく同じです。私はこれがデフォルトでCommon Lispには存在しないことに驚きました。 – MicroVirus
- 1. 一般的な方法 - コードの複製
- 2. データベースからオブジェクトを取り出す一般的な方法
- 3. 複製、シャーディング、一般的な案内
- 4. 一般的なlispイディオム - 良い方法がありますか?
- 5. ユーザーレイアウトを保存する一般的な方法はありますか?
- 6. Uriオブジェクトを作成する最も一般的な方法は?
- 7. 2dオブジェクトをデジタル画面に描画する一般的な方法はありますか?
- 8. この変換を行う一般的な方法はありますか?
- 9. 一般的にDbSet.FindメソッドをMoqでモックする方法はありますか?
- 10. ListDictionaryクラスの一般的な代替方法はありますか?
- 11. Microsoft AzureでLinux-VMを複製/複製する方法はありますか?
- 12. コルーチンベースのコードをプロファイルする一般的な手法はありますか?
- 13. アップロードされたファイルを複数のPythonフレームワークに渡す一般的な方法はありますか?
- 14. 文字列をオブジェクトに変換する一般的な方法
- 15. JSDoc - 一般的なキー名でオブジェクトをドキュメント化する方法
- 16. 一般的なハドソンのレポーターはありますか?
- 17. Vimには一般的な `filetype = code`がありますか?
- 18. 一般的なユニークカウント機能はありますか?
- 19. 良いCSSクラスチェッカーツールと一般的なクリーナーはありますか?
- 20. HasFlagには一般的な列挙型がありますか?
- 21. ブーストには一般的な「クリーンアップ」クラスがありますか?
- 22. C#4には一般的な属性がありますか?
- 23. ニューラルネットワークの一般的な形式はありますか
- 24. Pythonには一般的なメソッドがありますか?
- 25. 一般的な統計ボードソフトウェアはありますか?
- 26. の一般的な用語はありますか?ディレクトリエントリ?
- 27. AR :: RecordNotFoundを生成するよりも、404を投げる一般的な方法はありますか?
- 28. 一般的なオブジェクト内のリストにアクセスする方法
- 29. この方法を一般化する方法はありますか?
- 30. 一般的な方法と
スロットがバインドされているかどうかをテストするのに役立つ場合があります。次に、スロットがバインドされている場合にのみ、スロット値にアクセスします。 –
あなたが正しいです - 私はテストを追加しました。ありがとう! – danlei
広告されたとおりに動作します。以下は、より移植可能な方法で動作するようにするimport文です: '(:shadowing-import-from \t#openmcl-native-threads#:ccl \t#+ cmu#:pcl \t# + SBCL#:SB-PCL \t#+ lispworks番号:塩酸 \t#+アレグロ#:モップ \t#+ CLISP#:CLOS \t#:クラススロット#:スロット定義名) '。 – Inaimathi