lisp - 当应用于 Common Lisp 中的函数参数时,函数第 n 次访问哪个对象?

标签 lisp common-lisp

我在使用访问器函数 nth 时遇到了一些问题。我将一个列表传递给某个函数,并使用 nth 对函数中的列表元素进行新绑定(bind),然后当我从函数中调用列表时,它被修改了,这不是我想要的想!会发生什么?

一些例子

(defun test (x) (incf x)) => TEST
(setq a 1) => 1
(test a) => 2
a => 1

我理解上面发生的事情,但是如果我们将所有内容都更改为列表,就会发生一些我无法理解的事情

(defun test (x) (incf (nth 0 x))) => TEST
(setq a '(1)) => (1)
(test a) => 2
a => (2)

我原以为 a 是 (1),为什么它被修改了?我还尝试了其他功能,例如 carfirst,结果是一样的。

PS,我在 Lispworks 和 SBCL 中都试过了,结果一样。

最佳答案

(defun test (x) (incf x)) => TEST
(setq a 1) => 1
(test a) => 2
a => 1

您将 1 传递给 test。在测试中,您修改了局部变量 xa 没有改变,也不能那样改变——我们传递的是 a 的值,而不是对 a 的引用。

(defun test (x) (incf (nth 0 x))) => TEST
(setq a '(1)) => (1)
(test a) => 2
a => (2)

您将列表 (1) 传递给测试。列表不会被复制。局部变量 x 指向列表中的第一个 cons 单元格。然后将第一个 cons 单元格的 car 修改为 2。由于未复制列表,因此修改传递的列表。 a 也指向该列表的第一个 cons 单元格。所以它也是(2)

关于lisp - 当应用于 Common Lisp 中的函数参数时,函数第 n 次访问哪个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14019365/

相关文章:

lisp - 如何在 LISP 中覆盖 (defun eval (expr)) 函数

recursion - 普通口齿不清 : error "CDR LST should be a lambda expression"

function - 了解 Common Lisp 中的泛型函数?

recursion - 检查 Racket 中列表的升序

scheme - 在 if 语句中使用 Let

按普通 lisp 中的两个属性排序

lisp - 如何将此代码推广到多变量方程?

macros - Lisp:在宏中扩展属性名称

lisp - 实现 forkpty() 的 GNU Common Lisp 包

reflection - 符号函数的反义词是什么?