我正在努力理解为什么当我更改列表中的某些值时,某些 Lisp 数据会发生变化,而其他值则不会



我很难理解为什么当我更改l1列表的值时,双参数宏会更改结果列表中的值,而双列表不会。让我展示一下更清晰的步骤。我已经用值(1 2 3 4(定义了列表l1,

(setq l1 '(1 2 3 4))

然后我在下面加载这个代码

(defmacro double-args (&rest args)
`(let ((ret nil))
( dolist (x ,@args )
(setq ret (append ret (list x x))))

ret) )
(defun macroteste (&rest x) (double-args x))
;; first simple macro example:
(defmacro double-list (a-list)
(let ((ret (gensym)))
`(let ((,ret nil))
(dolist (x ,a-list)
(setq ,ret (append ,ret (list x x))))
,ret)))
;; use the macro:
(defun doublelistmacro (x)
(double-list x))

在这之后,我执行了宏macrotete,列表为l1,并存储在l2 中

(setq l2 (macroteste l1))

然后我用参数l1执行了doublelistmacro并存储在l3 中

(setq l3 (doublelistmacro l1))

所以我从l2开始,(1 2 3 4(并且从l3,(1 12 2 3 3 4(

然后我改变了l1的第二个值,(setf(第n个1 l1(9(我得到了以下结果:

l1

(1 9 3 4(

l2

(1 9 3 4(

l3

(1 12 2 3 3 4(

为什么当我改变l1时,l2也改变了,而l3没有?

首先,请注意:在代码中,您不应该修改像'(1 2 3 4)这样的文字常量。效果尚未确定。

在你的情况下,差异可以归结为这个

CL-USER 2 > (let ((foo (list 1 2 3 4)))
(let ((l1 (list foo foo))
(l2 (loop for e in foo append (list e e))))
(values l1 l2)))
((1 2 3 4) (1 2 3 4))
(1 1 2 2 3 3 4 4)

第一列表CCD_ 2是以原始列表两次作为其元素的新列表。第二列表CCD_ 3是一个全新构建的列表。

如果更改原始列表,它将在第一个结果中可见->它将它们直接作为元素。

它在第二个列表中不可见,因为该列表是全新的。

还要注意的是,宏使问题复杂化。因此,它们也没有什么意义。

相关内容

  • 没有找到相关文章

最新更新