题
我有一个带有“元素”插槽的节点类,其中包含一个带有数字和一个字母的列表,例如:
'(1 2 3 B 4 5 6)
(defclass node ()
((element :reader get-element
:writer set-element
:initform '()
:initarg :element
:documentation "The element"))
该程序的一部分应该采用“元素”插槽,将字母与数字之一交换,最后创建一个新的节点对象,将其交换为“元素”插槽。我已经有一个交换函数,该函数接收列表和该列表的两个成员,并使用旋转函数将其交换。
为了测试交换函数正在工作,我创建了以下代码,该代码存储在临时变量中,并将字母“ b”与列表中的数字交换:
(setf root (make-instance 'node))
(set-element '(1 2 3 b 4 5 6 7 8) root)
(setf temp(get-lement root))(交换temp'b 4)
问题在于,根对象的“元素”插槽与温度换成。奇怪的是,我尝试将交换函数更改为反向,并且不会修改两者中的任何一个。
我不知道是否有任何方法可以将插槽分配给变量或防止上述情况的方法。
谢谢。
解决方案
Reverse
创建并返回一个新列表。 Rotatef
(正如 setf
, incf
等等)修改一个地方。你不得不 copy-list
或者 copy-tree
您的 element
创建一个新列表,然后修改。
其他提示
其他一些评论:
而不是getter和setter方法,请使用访问者方法。这通常是首选。
列表是由列表或复制列表之类的功能创建的。写为“(1 b 2)的列表在源代码中是字面常数,不应更改。它在CL标准中不确定,如果您尝试更改文字列表,会发生什么。这可能会产生不必要的影响。如果您有文字列表,并且要修改它,则应首先使用copy-list(或copy-tree)复制并修改该副本。
您还需要了解反向和可能破坏性操作(例如NRREVERSE)等非破坏性操作之间的区别。如果您希望原始列表保持不变,请使用非破坏性操作。列表或序列操作的性质在每个操作的常见LISP HypersPEC中描述。