看到ANSI Common Lisp 第三章的游程编码时,就发现做者很准确的使用了list和cons来生成目标列表,虽然list是由cons扩展而来,区别也仅仅是最后一个元素的加入方式,因而勾起了以前对cons的疑问.编码
当看到下面的这样的代码:spa
(cons '(a b) '(c d))
你会以为输出结果是code
((a b) (c d))
仍是对象
((a b) c d)
虽然敲入一下代码,就知道是后者,但是,为何呢?blog
仔细看第三章cons的说明,发现cons放在c语言里面,无非就是一个以下的结构class
typedef struct _cons cons; struct _cons { void* content; //cons的内容 cons* next; }
而后咱们仔细观察cons的动做就会发现cons产生"参数个数-1"个新cons对象来链接这些参数,而且作相似以下的操做:扩展
cons new, a, b, c, d; a.content = (void *)'a'; a.next = &b; b.content = (void *)'b'; c.content = (void *)'c'; c.next = &d; d.content = (void *)'d'; new.content = (void *)&a; new.next = &c
你会发现(a b)成为了新cons对象的内容,而c成为了新cons对象的下一个对象,而d又恰好是c对象的下一个cons对象,很天然的new对象就和c,d这两个对象在一条链表上了.而a,b这2个对象虽然也组成了一个链表,可是是做为新对象的内容来存储的,也就是一条支线.链表
因此(cons '(a b) '(c d))的返回结果也很准确的反应了这条链表的维度关系((a b) c d).next