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