列表 是 Common Lisp 中非常常见的一种数据类型。
它们由一串 cons 单元组成。
每个car都是列表中的一个元素,每个cdr要么是下一个 cons 单元,要么是一个作为结尾的原子。
以空列表结尾的列表称为“正规列表”。
以不是空列表的原子结尾的列表称为“点对列表”(这是根据它的打印方式命名的:(cons 'a 'b) ;=> (a . b))。
如果列表中的某个 cons 单元是更靠后的某个 cons 单元的cdr,那么这个列表也可能是循环的,也就是循环列表。
例如:(let ((x (list 1))) (setf (cdr x) x) (write x :stream t :circle t) :done)。
处理循环列表时要小心:如果在打印时没有把 *print-circle* 绑定为t,就会导致无限循环,并锁死 REPL(在这个例子里,由于给write指定了:circle t,*print-circle会被绑定为t)。
你可以用任意数量的列表调用append,包括 1 个或 0 个:
(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '())) ; => (A B C)
(append '(a b c)) ; => (A B C)
(append) ; => ()
除了append,还可以用nconc,它的结果相同,但副作用是会修改原来的列表。使用nconc时要小心,因为它可能带来出人意料的效果。