为什么 (nil . nil) 在 SBCL 中计算结果为 (nil) 而不是 nil?

问题描述 投票:0回答:1

在 SBCL REPL 中,为什么输入 (nil . nil) 计算结果为 (nil) 而不仅仅是 nil?

如果空列表是 cons 单元的两个“元素”都为零的列表,为什么它们不一样?

我对此的假设是 SBCL 做出以下评估:

(car '()) => nil
(cdr '()) => nil
(car '(nil . nil)) => nil
(cdr '(nil . nil)) => nil

然而:

'() => nil
'(nil . nil) => (nil)
common-lisp sbcl
1个回答
0
投票
如果给定

car

 作为参数,则 
cdr
nil
返回
nil
。让我们先了解一下
nil
这个词,看看您实际上正在看什么值。

(car '()) == '()
(cdr '()) => nil

car
cdr
得到一个空列表,所以我们返回
nil
,或
()

(car '(nil . nil)) => nil
(cdr '(nil . nil)) => nil

现在,

(nil . nil)
(() . ())
。也就是说,这是一个 cons cell,其 car 和 cdr 都是
nil

当 cons 单元格末尾有

. ()
时,我们可以通过省略尾随的
nil
来在符号上缩短它。这只是为了符号方便,所以根据我们的符号,
(() . ())
可以写成
(())
(nil)
。请注意,这不会改变该值。最明确的写法仍然是(() . ()),但为了便于阅读,我们也可以写得更短。

如果空列表是 cons 单元的两个“元素”都为零的列表,为什么它们不一样?

这是不正确的。空列表根本不是 cons 单元格。空列表是原子
nil

。它是一个符号,就像'foo

'pizza
'common-lisp
一样。这只是我们选择用于此目的的一个符号。但是
nil
没有
汽车或CDR单元。碰巧的是,让
(car nil)
(cdr nil) 成为
nil
作为算法的极端情况通常很方便,因此
函数
car
cdr
nil
上有特殊的行为。但
nil
不是
一个缺点细胞。
> (consp nil)
nil
> (consp '())
nil
> (consp '(1 . 2))
T

根据

系统类
LIST

list

类型可以描述为
类型 
cons

null

形成类型列表的详尽分区。


因此 Common Lisp 中的 
list

被定义为“cons cell 或特殊值
nil

”。值得注意的是,nil本身并不是一个缺点细胞。

    

© www.soinside.com 2019 - 2024. All rights reserved.