lisp中的cons

看到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

相关文章
相关标签/搜索