我有一个Node类,它有一个'element'插槽,其中包含一个带有数字和一个字母的列表,例如:
'(1 2 3 b 4 5 6)
(defclass node ()
((element :reader get-element
:writer set-element
:initform '()
:initarg :element
:documentation "The element"))
该程序的一部分应该采用'element'插槽,将字母与其中一个数字交换,最后创建一个新的Node对象,将交换列表作为其“元素”插槽。我已经有一个交换函数,它接收一个列表和该列表的两个成员,并使用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一起交换。奇怪的是,我尝试将交换功能更改为反向,并且不会修改这两者中的任何一个。
我不知道是否有任何方法可以为变量分配插槽或防止上述情况发生。
感谢。
答案 0 :(得分:3)
其他一些评论:
使用访问器方法代替getter和setter方法。这通常是首选。
使用LIST或COPY-LIST等功能创建列表。写为'(1 b 2)的列表在源代码中是文字常量,不应更改。在CL标准中未定义如果您尝试更改文字列表会发生什么。这会产生不良影响。如果您有文字列表并且想要修改它,则应首先使用COPY-LIST(或COPY-TREE)复制它并修改该副本。
您还需要了解REVERSE等非破坏性操作与NREVERSE等破坏性操作之间的区别。如果希望原始列表保持不变,请使用非破坏性操作。每个操作的Common Lisp Hyperspec中描述了列表或序列操作的性质。
答案 1 :(得分:2)
Reverse
创建并返回一个新列表。 Rotatef
(就像setf
,incf
等)修改地点。您必须copy-list
或copy-tree
element
创建一个新修改的列表。