emacs - emacs lisp 中 nconc 的奇怪行为

标签 emacs elisp

我有以下功能(简化为该版本):

(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/

相关文章:

Emacs:在 minibuffer 中更改 Ido 完成键映射

emacs - elisp 中的变量绑定(bind)

emacsclient --create-frame 打开 *scratch* 即使设置了初始缓冲区选择

emacs - 分析 Emacs Lisp 行为不当的技巧?

Emacs Dired - C-x C-f 创建一个新文件给我现有文件的建议

emacs - 在 Emacs 中显示大写锁定、数字锁定和移位键的状态

list - 将文件读入 elisp 中的对列表

Emacs org-mode - 如何在不挂起 Emacs 的情况下使用后台进程运行 shell 脚本

Emacs:如何定义目录的 'bookmark'变量

emacs - 邪恶的模式特定或缓冲区本地文本对象?