为什么必须使用 null 才能在方案中获得正确的列表?
我意识到这完全是一个n00b问题,但我很好奇,我想我在这里可能比其他地方得到更好的解释。这是一个列表(我正在使用 Dr.Scheme),
> (list 1 2 3)
(1 2 3)
我认为这只是糖:
> (cons 1 (cons 2 (cons 3 null)))
(1 2 3)
另一方面,它还有其他作用:
> (cons 1 (cons 2 3))
(1 2 . 3)
我的问题是,为什么会有所不同?要求列表末尾为空有什么意义?
I realize this is a total n00b question, but I'm curious and I thought I might get a better explanation here than anywhere else. Here's a list (I'm using Dr. Scheme)
> (list 1 2 3)
(1 2 3)
Which I think is just sugar for this:
> (cons 1 (cons 2 (cons 3 null)))
(1 2 3)
This, on the other hand, does something else:
> (cons 1 (cons 2 3))
(1 2 . 3)
My questions is, why is that different? What's the point of requiring the null at the end of the list?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
列表的定义是递归的。
所以这些是列表:
您给出的最后一个示例 cons 2 3 不符合此列表定义,因此它不是列表。也就是说 cons 接受一个项目和一个列表。 3 不是列表。
The definition of a list is recursive.
So these are lists:
The last example you gave cons 2 3 does not conform to this list definition so its not a list. That is cons accepts an item and a list. 3 is not a list.
cons
将一个新元素添加到列表的开头,因此您在编写时所做的事情是:递归地将项目添加到不断增长的列表中,从
null
开始,它被定义为空列表()
。当您调用(cons 2 3)
时,您并不是从空列表开始,因此不会通过在其开头附加 2 来构造列表。cons
adds a new element to the beginning of a list, so what you're doing when you write:is recursively adding items to an ever-growing list, starting with
null
, which is defined to be the empty-list()
. When you call(cons 2 3)
you're not starting with the empty list to begin with, so are not constructing a list by appending 2 to its beginning.Lisp,包括Scheme,都是动态类型的,“Lisp 方式”是在单个数据结构上拥有许多函数,而不是针对不同任务使用不同的数据结构。
那么问题是“在列表末尾要求 null 有什么意义?”这个问题不太合适。
cons
函数不要求您提供cons
对象或nil
作为其第二个参数。如果第二个参数不是 cons 对象或 nil,那么您将得到一对而不是列表,并且运行时不会使用列表表示法打印它,而是使用点。因此,如果您想构造形状像列表的东西,请为
cons
提供一个列表作为其第二个参数。如果你想构造其他东西,那么给cons
其他东西作为它的第二个参数。如果您想要一个恰好包含两个值的数据结构,则对非常有用。对于一对,您不需要末尾的 nil 来标记其长度,因此效率更高一些。对列表是键到值映射的简单实现; common lisp 具有支持此类属性列表的函数作为其标准库的一部分。
因此,真正的问题是“为什么可以使用相同的 cons 函数构造对和列表?”,而答案是“当您只需要一个数据结构时,为什么要使用两个数据结构?”
Lisps, including Scheme, are dynamically typed, and 'the lisp way' is to have many functions over a single data structure rather than different data structures for different tasks.
So the question "What's the point of requiring the null at the end of the list?" isn't quite the right one to ask.
The
cons
function does not require you to give acons
object ornil
as its second argument. If the second argument is not acons
object ornil
, then you get a pair rather than a list, and the runtime doesn't print it using list notation but with a dot.So if you want to construct something which is shaped like a list, then give
cons
a list as its second argument. If you want to construct something else, then givecons
something else as its second argument.Pairs are useful if you want a data structure that has exactly two values in it. With a pair, you don't need the nil at the end to mark its length, so it's a bit more efficient. A list of pairs is a simple implementation of a map of key to value; common lisp has functions to support such property lists as part of its standard library.
So the real question is "why can you construct both pairs and lists with the same
cons
function?", and the answer is "why have two data structures when you only need one?"cons 语句用于分配 car 为 obj1 且 cdr 为 obj2 的对。
因此,有必要以 null 结束 cons 语句,以便我们知道我们已到达列表末尾。
在该示例中,cdr将是一对<2,3>。其中 2 是汽车,3 是 cdr。不等于:
A cons statement is used to allocate a pair whose car is obj1 and whose cdr is obj2
Therefore, it is necessary to end a cons statement with a null so that we know we are the end of the list.
In that example, the cdr would be a pair <2,3> where 2 is the car and 3 is the cdr. Not the same as: