cons
在以下两个项目上的工作方式有什么区别:
(cons 1 '(2))
; (1 2)
(cons 1 2)
; (1 . 2)
两者都评估pair?
为真实,所以我很好奇两者有何不同。
是否产生:
--------
| 1 | 2 |
-------
另一个产生:
-------- --------
| 1 | -> | | 2 | X |
------- -------
或者有什么区别?
在这两种情况下,cons
的工作方式没有区别。
cons
是一样的。cons
产生的任何东西都会导致pair?
返回true
。就这么简单。
您一起cons
的两件事在两个代码段之间是不同的。
在第二个片段中,(cons 1 2)
,它是两个数字。我们避免任何对表现效率的倾向,只对概念的正确性感兴趣,我们认为这是创造
---------
| * | * |
---------
| |
v v
1 2
第一个代码段(cons 1 '(2))
使用数字1
和由'(2)
创建的对象:
---------
| * | * |
---------
| |
v v
1 ---------
| * | * |
---------
| |
v v
2 NIL
您需要了解如何在 Scheme 中定义正确的列表。通过cons
元素来创建正确的列表,其中cdr
部分是另一个cons
单元格或空列表'()
。问题中的第一个示例是一个正确的列表:
(cons 1 '(2))
(cons 1 (cons 2 '())) ; this is the same as above
=> '(1 2)
当然,我们也可以创建不遵循规则的任意cons
单元格。问题中的第二个示例证明了这一点,它是一个cons
单元格,其中cdr
部分不是另一个cons
单元格或空列表,因此它不是一个正确的列表:
(cons 1 2)
=> '(1 . 2)
正确的列表始终以 NIL 结尾。 即,第一个代码示例生成两个 cons-cell,一个在另一个单元内,最里面的 con-cell 终止于 nil。然而,第二个示例不遵循标准列表的规则,因为它只是一个具有两个非 nil 值的 cons-cell。
(cons 1 '(2))
CLISP> (1 2) ; This list is actually (cons 1 (cons 2 NIL))
(cons 1 (cons 2 NIL))
CLISP> (1 2) ; Same as above
但是,如果您将 NIL 排除在外,REPL 将用点指示。
(cons 1 2) ; this cons-cell is not terminated by NIL
CLISP> (1 . 2)
(cons 1 (cons 2 (cons 3 4))) ; A longer example
CLISP> (1 2 3 . 4) ; Notice the dot to indicate last element is non-nil.