没有任何上下文,这很难理解。
例子:
(setq list1 (list 1 2 3 4))
我们现在有一个包含四个数字的列表。变量list1
指向第一个缺点。
如果我们看一个破坏性的反转,我们正在谈论一个可能改变 cons 单元的操作。有不同的方法可以颠倒这个列表。
例如,我们可以取 cons 单元格并反转它们。然后第一个 cons 单元格是最后一个。然后必须将该 cons 单元的 cdr 更改为NIL
.
CL-USER 52 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
CL-USER 53 > (nreverse list1)
(4 3 2 1)
现在我们的变量list1
仍然指向同一个 cons 单元格,但是它的 cdr 已经改变了:
CL-USER 54 > list1
(1)
为了确保变量指向一个反向列表,程序员有责任更新变量并将其设置为nreverse
操作的结果。人们也可能试图利用list1
指向最后一个缺点的可观察结果。
以上是 Lisp 开发人员通常所期望的。大多数反向实现似乎都是这样工作的。但是 ANSI CL 标准中没有规定如何nreverse
实现。
那么,改变 CAR 意味着什么呢?
让我们看一下的替代实现nreverse
:
(defun nreverse1 (list)
(loop for e across (reverse (coerce list 'vector))
for a on list do
(setf (car a) e))
list)
上面的函数让我们的 cons 细胞链完好无损,但改变了car。
CL-USER 56 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
现在让我们使用新版本,nreverse1
.
CL-USER 57 > (nreverse1 list1)
(4 3 2 1)
CL-USER 58 > list1
(4 3 2 1)
现在你看到了不同之处:list1
仍然指向整个列表。
摘要:需要注意的是,可能有不同的实现nreverse
。不要利用通常的行为,其中一个变量将指向最后一个缺点。只需使用的结果,nreverse
一切都很好。
旁注:第二个版本可以在哪里使用?
Lisp 机器上的一些 Lisp 实现允许列表的紧凑型向量表示。如果在这样的 Lisp 实现中,可以对这样的列表进行 nreverse,则实现者可以提供一个有效的类似向量的 nreverse。