列表作为惯例

某些语言包括列表数据结构。Common Lisp 和 Lisp 系列中的其他语言广泛使用列表(Lisp 的名称基于 LISt 处理器的思想)。但是,Common Lisp 实际上并不包含基本列表数据类型。相反,列表按惯例存在。该公约取决于两个原则:

  1. 符号 nil 是空列表。
  2. 非空列表是一个 *cons 单元,*其 car 是列表的第一个元素,其 cdr 是列表的其余部分。

这就是列表的全部内容。如果你已经阅读了名为什么是缺点单元格的示例*?*,那么你知道汽车是 X 并且 cdr 是 Y 的 cons 单元可以写成 (X.Y) 。这意味着我们可以根据上述原则编写一些列表。元素 1,2 和 3 的列表很简单:

(1 . (2 . (3 . nil)))

但是,由于列表在 Lisp 系列语言中非常常见,因此除了简单的点对符号之外,还有特殊的打印约定。

  1. 符号 nil 也可以写成 ()
  2. 当一个 cons 单元的 cdr 是另一个列表( () 或者 cons 单元格时,不使用点对符号来写一个 cons 单元,而是使用 list notation

列表符号通过几个示例最清楚地显示:

(x . (y . z))   === (x y . z)
(x . NIL)       === (x)
(1 . (2 . NIL)) === (1 2)
(1 . ())        === (1)

这个想法是列表的元素在括号内按顺序写入,直到达到列表中的最后一个 cdr。如果最终的 cdr 为 nil (空列表),则写入最后的括号。如果最终的 cdr 不是 nil (在这种情况下列表被称为不正确的列表 ),则写入一个点,然后写入最终的 cdr。