-
Notifications
You must be signed in to change notification settings - Fork 21
/
02.4 pair、list和Racket的语法
48 lines (30 loc) · 1.92 KB
/
02.4 pair、list和Racket的语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2.4 pair、list和Racket的语法
cons函数实际上接受任何两个值,而不只是第二个参数的列表。当第二个参数不是empty,并且不是自己通过cons产生,结果以一种特殊的方式打印出来。两值加入cons被打印在括号之间,但在两者之间有一个点(即,一个被空格环绕的句点):
> (cons 1 2)
'(1 . 2)
> (cons "banana" "split")
'("banana" . "split")
因此,由cons产生的值并不总是列表。一般来说,cons的结果是一个对(pair)。更传统的cons?函数的名字是pair?,我们从现在开始使用传统的名字。
名字rest对非列表对没有意义;first和rest更传统的名字分别是car和cdr。(当然,传统的名字也是没有意义。)。请记住,“a”出现在“d”之前,cdr被声明为“可以”。
例子:
> (car (cons 1 2))
1
> (cdr (cons 1 2))
2
> (pair? empty)
#f
> (pair? (cons 1 2))
#t
> (pair? (list 1 2 3))
#t
Racket对数据类型和表的关系本质上是一种历史的好奇心,连同打印的点符号和滑稽的名字car和cdr。但是,对在Racket的文化、规范和实施有着深刻的联系,所以他们能在语言中生存下来。
在犯错误时你很可能会遇到非列表对,例如不小心把参数颠倒过来cons:
> (cons (list 2 3) 1)
'((2 3) . 1)
> (cons 1 (list 2 3))
'(1 2 3)
非列表对有时是有意使用的。例如, make-hash函数取得一个对的列表,其中每个对的car是一个键,cdr是任意值。
对新的Racket程序员唯一更困惑的情况莫过于非列表对是对对的打印习惯,第二个元素是一个对而不是一个列表:
> (cons 0 (cons 1 2))
'(0 1 . 2)
一般来说,打印一个对的规则如下:除非该点紧接着是一个开括号,否则使用点表示法。在这种情况下,去掉点、开括号和匹配的括号。由此,“(0 . (1 . 2)“变成”(0 1 . 2),(1 . (2 . (3 . ())))变成为'(1 2 3)。