http://www.aiai.ed.ac.uk/~jeff/lisp/cl-pitfalls将此列为Common Lisp陷阱之一
您认为会修改CDR的破坏性功能可能会修改CAR.(例如,NREVERSE.)
我不确定我应该采取什么预防措施.我可以从NREVERSE修改CDR的事实中采取的常规预防措施是仅当列表(参数)不与我的变量稍后可能引用的任何其他列表共享尾部时使用NREVERSE(除了变量我保存返回值)至).我应该从NREVERSE可以修改CAR的事实中采取什么预防措施?这件事需要注意什么?
Rai*_*wig 12
没有任何背景,这很难理解.
例:
(setq list1 (list 1 2 3 4))
Run Code Online (Sandbox Code Playgroud)
我们现在有一个四个数字的列表.变量list1指向第一个缺点.
如果我们看一个破坏性的反向,我们正在讨论一个可能改变缺陷细胞的操作.如何反转此列表有不同的方法.
例如,我们可以采取利弊细胞并将其逆转.然后是第一个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)
Run Code Online (Sandbox Code Playgroud)
现在我们的变量list1仍指向相同的cons单元格,但其cdr已更改:
CL-USER 54 > list1
(1)
Run Code Online (Sandbox Code Playgroud)
为了确保变量指向反转列表,程序员有责任更新变量并将其设置为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)
Run Code Online (Sandbox Code Playgroud)
以上功能让cons细胞链保持完整,但改变了汽车.
CL-USER 56 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
Run Code Online (Sandbox Code Playgroud)
现在让我们使用新版本nreverse1.
CL-USER 57 > (nreverse1 list1)
(4 3 2 1)
CL-USER 58 > list1
(4 3 2 1)
Run Code Online (Sandbox Code Playgroud)
现在你看到了不同之处:list1仍然指向整个列表.
总结:需要注意的是,有可能的不同实现nreverse.不要利用通常的行为,然后变量将指向最后的缺点.只需使用结果,nreverse一切都很好.
旁注:第二个版本可以在哪里使用?
Lisp机器上的一些Lisp实现允许一个紧凑的矢量表示列表.如果在这样的Lisp实现上,可以反转这样的列表,则实现者可以提供类似向量的有效向量.
| 归档时间: |
|
| 查看次数: |
331 次 |
| 最近记录: |