R:“看,在天空中!拉姆达信号!一个公民有麻烦拉姆达人!”
LM:“我明白了!而且我有他们需要的盒子艺术。”
在 Lisps 中,列表是单链接的数据结构,由称为cons 单元的元素组成。这些细胞中的每一个都是一个结构,由
- 指向值的指针
- 指向下一个单元格的指针
由于历史原因,它们分别被称为car和cdr 。这是代表 3 元素列表的传统盒子艺术:
Structure: (car . cdr -)--->(car . cdr -)--->(car . cdr)
| | | |
v v v v
Values: 1 2 3 nil
car
和函数允许您使用cdr
这种低抽象级别的列表,并返回相应单元格的值。因此,car
返回单元格的“值”,并cdr
取消对列表其余部分的引用。nthcdr
是cdr
为了方便起见的概括。
返回的值cdr
是对原始数据结构的引用,该结构在此级别是可变的。如果你改变了一个 cons-cell 的 cdr 的值,你就改变了列表的底层结构。
鉴于:
let A = '(1 2) ~= (1 . -)-->(2 . nil)
let B = '(3 4) ~= (3 . -)-->(4 . nil)
将 cdr 设置(cdr A)
为 B 将破坏性地连接 A 和 B 使得 A 现在是以下结构:
A B
(1 . -)-->(2 . -)-->(3 . -)-->(4 . nil)
正如我们所展示的,nil
一个单元格的 cdr 中的值代表列表的结尾——没有什么可以遍历的了。如果我们将 A 的 cdr 设置为nil
,我们对列表进行 lobotomise,使得 A 现在
A
(1 . nil) <- [Not pointing to anything - the rest of the list shall go wanting]
这几乎就是你所做的——你已经使用低级函数改变了底层数据结构。:) 通过将单元格的其中一个 cdrs 设置为nil
,您已将列表的结尾剪掉了。