什么是Common Lisp Cons Cell的定义? Cons Cell和标准链表项有何不同?毕竟,Cons Cell和链表项都有一个值和指向下一个单元格或项的指针...这个理解是错误的吗?
什么是Common Lisp Cons Cell的定义? Cons Cell和标准链表项有何不同?毕竟,Cons Cell和链表项都有一个值和指向下一个单元格或项的指针...这个理解是错误的吗?
Cons单元通常包含两个指针,可以指向任何东西。通常的用法是使用左侧指针指向“值”,使用右侧指针指向另一个Cons单元(或nil)。
Cons单元格更接近于二叉树节点而非链表节点。car和cdr返回两个子节点,它们可以是nil、原子或其他cons单元格。
('tofu . 1)
是一个合法的 cons cell。 - Chuckcons
单元是由cons
、car
和cdr
组成的合同的三分之一,要求它们像对一样运作,正如其他人所提到的那样。cons
。(define (cons a b) (lambda (x) (x a b)))
(define (car x) (x (lambda (a b) a)))
(define (cdr x) (x (lambda (a b) b)))
这个定义完全存在于Lisp的定义和函数世界中,甚至没有考虑对象是存储为值还是引用; 然而它们可以作为原始对象的替代品(不考虑可变性或其他特殊用途)。
c
中,则(car c)
返回第一个值,(cdr c)
返回第二个值。car
包含节点值,cdr
包含对下一个节点或nil(空列表)的引用,以表示列表的结尾。当原始函数返回或接受列表时,这是列表呈现的格式。l
,(car l)
给出第一个元素(第一个cons单元格中的值),(cdr l)
返回列表的尾部(列表中的下一个cons单元格)。我认为其他回答虽然准确,但没有明确一件事。
在传统的C++链表实现中,两个字段(比如说val
和next
)是有类型的。 next
被定义为指向列表中的另一个节点,null
是终止符。你不能使用 next
指向除了另一个节点以外的任何东西。
Lisp 是动态类型的,因此 cons 单元格中的任何字段都可以是任何东西(原子或引用)。您可以使用 cons 单元格实现链表(这就是 Lisp 列表的全部内容:带有 nil
终止符的 cons 单元格链),但您也可以在每个字段中放置任意值,例如使用 cons 单元格作为坐标对、树节点等等。
您甚至可以将它们组合起来;例如,x
y
坐标的列表:
;; (cons foo (cons bar nil)) == (list foo bar)
(cons
(cons 5 4)
(cons (cons 9 10) nil))
=>
((5 . 4) (9 . 10))
map
、dolist
等)都是假设你将值放在car
中,另一个列表放在cdr
中的函数。car
指向下一个cons单元,cdr
指向值!如果要使用链表节点来实现这个功能,则需要重新定义类或数据结构以更改类型。
nil
)都是一个cons单元,但不是每个cons单元都是一个列表(如果它的cdr
不是一个列表)。 - mihi