下面的代码有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
为什么会这样呢?这种行为是属性列表特有的吗?
In foo
, z
绑定到文字表达式'(stuff nil)
。该功能会破坏性地改变z
,从而破坏性地改变了文字的值。 LISP 在这种情况下的行为取决于实现。某些实现会乖乖地改变文字值(如您的情况)。其他实现将文字放置在只读内存位置,如果您尝试修改这些文字,则会失败。
要获得所需的行为,请使用COPY-LIST
制作可以安全修改的文字副本:
(defun foo (m)
(let ((z (copy-list '(stuff nil))))
(push m (getf z 'stuff))
(print z)))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)