我正在阅读“在lisp上”,并遇到了这段代码(我简化了一下)。
CL-USER> (defun foo ()
'(a b c))
FOO
CL-USER> (foo)
(A B C)
CL-USER> (nconc * '(D E))
(A B C D E)
CL-USER> (foo)
(A B C D E)
CL-USER> (defun foo ()
(list 'a 'b 'c))
STYLE-WARNING: redefining FOO in DEFUN
FOO
CL-USER> (foo)
(A B C)
CL-USER> (nconc * '(D E))
(A B C D E)
CL-USER> (foo)
(A B C)
*
究竟是什么意思?是以前的函数调用吗?它适合在现实世界的代码中使用吗?
为什么(nconc * '(D E))
会更改第一个foo
函数的返回值?
我一直认为(list 'a 'b 'c)
和'(a b c)
是一样的?有什么区别?
答案 0 :(得分:14)
每次评估时,对LIST的调用都会创建一个新列表。列表文字可能在编译后放在只读内存段中。然后使用NCONC对列表进行破坏性更新是有问题的,可能会产生不确定的后果(分段错误,更改未来引用的文字,或者根本没有任何内容)。
答案 1 :(得分:8)
变量*
,**
和***
由语言standard指定,在测试时非常有用。它们是REPL的一个特性,因此不是,也不应该在“真实世界代码”中有用。