我有以下功能(简化为该版本):
(defun append-test (xs)
(let ((ys `(foo ,(nconc `(bar) xs))))
(nconc ys `((baz)))))
如果我多次评估该函数(append-test '((foo)))
列表的大小不断增加,但我不明白为什么。 nconc 修改原始列表,但由于原始列表是函数参数或 let 变量,因此每次调用都应该重新创建它们,对吗?这里发生了什么?
最佳答案
如果将 `(bar)
更改为 (list 'bar)
,则代码每次都会返回相同的结果。
nconc
修改除最后一个参数之外的所有参数。显然,如果第一个参数是 '(bar)
,那么函数定义中包含的引用列表将被修改,我们希望看到您看到的结果。显然,使用不包含任何逗号的反引号表达式等同于使用带引号的列表。
实际上,下面的代码保留了反引号,但向列表的 cdr 添加了一个无意义的表达式。显然,这使得每次调用该函数时都会分配一个新列表,因此每次都会返回相同的结果:
(defun append-test (xs)
(let ((ys `(foo ,(nconc `(bar . ,(ignore)) xs))))
(nconc ys `((baz)))))
关于emacs - emacs lisp 中 nconc 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25157349/