setf 似乎在 aref 给出时改变了它的两个参数

setf seems to change both its arguments when they are given by aref

在 Lisp 中,我定义了一个数组 a,然后让 b 等于 a。我现在想将 b 的条目重新定义为等于 a 中的另一个条目,如下所示:

(setf a (make-array '(2 2) :initial-contents '((1 2) (3 4))))
(setf b a)
(setf (aref b 0 0) (aref a 0 1))

所以现在,b 将是 #2A((2 2) (3 4)),这一切都很好。但令我困惑的是 a 现在 #2A((2 2) (3 4)).

我的问题是:为什么将 setf 应用于 b 的条目也会更改 a?我可以通过使用 (setf x (aref a 0 1)) 引入一个中间变量然后应用 (setf (aref b 0 0) x) 来解决这个问题,但这对我来说似乎是一个奇怪的解决方法。

第二行中的 (setf b a) 在其他语言中有时被称为 shallow copy。也就是说,b 不会成为数组 a 的独立副本,而是成为完全相同数组的另一个名称。因此,当您修改 b 时,您也在修改 a

如果你想让b成为一个真实的、独立的数组副本("deep copy"),那么你需要分配一个新数组并复制[=12=的元素] 进去。一种方法是针对一维数组使用 copy-seq function. For fancier arrays you might also look at this question about how to copy 2d arrays,其中讨论了一些可用的库和方法。