1

数字と1文字のリストを含む'element'スロットを持つNodeクラスがあります。次に例を示します。

'(1 2 3 b 4 5 6)


(defclass node ()
  ((element :reader get-element
            :writer set-element
            :initform '()
            :initarg :element
            :documentation "The element"))

プログラムの一部は、「要素」スロットを取得し、文字を数字の1つと交換し、最後に、交換されたリストを「要素」スロットとして使用して新しいノードオブジェクトを作成することになっています。私はすでにリストとそのリストの2つのメンバーを受け取るスワップ関数を持っており、rotatef関数を使用してそれらをスワップします。

スワップ関数が機能していることをテストするために、一時変数に要素を格納し、文字「b」をリスト内の数値と交換する次のコードを作成しました。


(setf root (make-instance 'node))
(set-element '(1 2 3 b 4 5 6 7 8) root)

(setf temp (get-element root)) (swap temp 'b 4)

問題は、ルートオブジェクトの「element」スロットがtempとともに交換されることです。不思議なことに、スワップ関数をリバースに変更しようとしましたが、2つは変更されません。

変数にスロットを割り当てる方法や、上記の発生を防ぐ方法があるかどうかはわかりません。

ありがとう。

4

2 に答える 2

3

他のいくつかの意見:

  • getterおよびsetterメソッドの代わりに、アクセサーメソッドを使用します。通常はそれが推奨されます。

  • リストは、LISTやCOPY-LISTなどの関数を使用して作成されます。'(1 b 2)と書かれたリストは、ソースコードではリテラル定数であり、変更しないでください。リテラルリストを変更しようとするとどうなるかは、CL標準では定義されていません。これは望ましくない影響を与える可能性があります。リテラルリストがあり、それを変更する場合は、最初にCOPY-LIST(またはCOPY-TREE)を使用してそれをコピーし、そのコピーを変更する必要があります。

  • また、REVERSEのような非破壊的操作と、NREVERSEのような破壊的操作の違いを学ぶ必要があります。元のリストを変更しない場合は、非破壊操作を使用します。リストまたはシーケンス操作の性質は、各操作のCommonLispHyperspecに記載されています。

于 2010-09-25T23:21:50.007 に答える
2

Reverse新しいリストを作成して返します。 Rotatef(と同じようsetfincf)場所を変更します。新しいリストを作成するか、作成してから変更する必要が ありcopy-listますcopy-treeelement

于 2010-09-25T23:11:20.640 に答える