Common Lisp中的属性列表是否引用了某些全局状态?
下面的代码将Common Lisp中的属性列表是否引用了某些全局状态?,lisp,common-lisp,sbcl,Lisp,Common Lisp,Sbcl,下面的代码将z作为一个局部变量,但其行为就像是一个全局变量: (defun foo (m) (let ((z '(stuff nil))) (push m (getf z 'stuff)) (print z))) (foo 1) (foo 2) (foo 3) 我希望输出是 (STUFF (1)) (STUFF (2)) (STUFF (3)) T 但是当用SBCL运行它时,我明白了 (STUFF (1)) (STUFF (2 1)) (STUFF (3 2
z
作为一个局部变量,但其行为就像是一个全局变量:
(defun foo (m)
(let ((z '(stuff nil)))
(push m (getf z 'stuff))
(print z)))
(foo 1)
(foo 2)
(foo 3)
我希望输出是
(STUFF (1))
(STUFF (2))
(STUFF (3))
T
但是当用SBCL运行它时,我明白了
(STUFF (1))
(STUFF (2 1))
(STUFF (3 2 1))
T
为什么会这样?这种行为是属性列表特有的吗?在
foo
中,z
绑定到文本表达式'(stuff nil)
。函数以破坏性方式更改z
,从而破坏性地更改文本的值。LISP在这种情况下的行为取决于实现。一些实现将顺从地更改文本值(如您的情况)。其他实现将文本放在只读内存位置,如果尝试修改这些文本,则将失败
要获得所需的行为,请使用COPY-LIST
复制可以安全修改的文本:
(defun foo (m)
(let ((z (copy-list '(stuff nil))))
(push m (getf z 'stuff))
(print z)))
我认为更惯用的方法是使用
LIST
,如(let((z(LIST'stuff nil))…)
可能重复的