Lisp 当aref给出两个参数时,setf似乎会改变它们

Lisp 当aref给出两个参数时,setf似乎会改变它们,lisp,Lisp,在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)(3 4)),这一切都很好。但让我困惑的是a现在也是#2A((22)(34)) 我的问题是:为什么对b的条目应用setf也改变了a?我可以通过使

在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)(3 4))
,这一切都很好。但让我困惑的是
a
现在也是
#2A((22)(34))

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

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

如果希望
b
是数组的真实、独立副本(“深度副本”),则需要分配一个新数组,并将
a
的元素复制到其中。实现这一点的一种方法是对一维数组使用函数。对于更高级的阵列,您还可以查看这篇文章,其中介绍了一些可用的库和方法