1.列表(Lists)
cons把两个对象结合成一个有两部分的对象,称之为 Cons 对象。概念上来说,一个 Cons 是一对指针; 第一个是 car ,第二个是 cdr 。
任何非空的列表,都可以被视为一对由列表第一个元素及列表其余元素所组成的列表。
[1]> (setf x (list 'a 'b 'c))
(A B C)
[2]> (car x)
A
[3]> (cdr x)
(B C)
看图理解cons。
[caption id="attachment_801" align="alignnone" width="298" caption="lisp list"][/caption]
可以这么些:
[8]> (setf y (cons 'a (cons 'b (cons 'c nil))))
(A B C)
与图中所画内容相对应了
嵌套列表
[9]> (setf z (list 'a (list 'b 'c) 'd))
(A (B C) D)
[10]> (car (cdr z))
(B C)
[caption id="attachment_802" align="alignnone" width="300" caption="lisp嵌套列表"][/caption]
如果参数是一个 Cons 对象,函数 consp 返回真。
(defun our-listp (x)
(or (null x) (consp x)))
因为所有不是 Cons 对象的东西就是一个原子 (atom),判断式 atom 可以这样定义:
NIL 是一个原子,同时也是一个列表。
(null x)就是判断x为nil时,返回t。当然空列表也是nil。
2.等式 (Equality)
每一次你调用 cons 时, Lisp 会配置一块新的内存给两个指针。所以如果我们用同样的参数调用 cons 两次,我们得到两个数值看起来一样,但实际上是两个不同的对象:
[14]> (eql (cons 'a nil) (cons 'a nil))
NIL
本质上 equal 若它的参数打印出的值相同时,返回真:
[15]> (equal (cons 'a nil) (cons 'a nil))
T
3.lisp的指针
书上给了一个例子:
[22]> (setf x '(a b c))
(A B C)
[23]> x
(A B C)
[24]> (setf y x)
(A B C)
[25]> y
(A B C)
[26]> (eql x y)
T
当我们给 y 赋一个相同的值时, Lisp 复制的是指针,而不是列表。当你赋一个值给变量或将这个值存在数据结构中,其实被储存的是指向这个值的指针。当你要取得变量的值,或是存在数据结构中的内容时, Lisp 返回指向这个值的指针。
函数 copy-list 接受一个列表,然后返回此列表的复本。
[27]> (setf y (copy-list x))
(A B C)
[28]> (eql x y)
NIL
4.列表的存取
[29]> (nth 0 '(a b c ))
A
[30]> (nth 1 '(a b c ))
B
[35]> (nthcdr 0 '(a b c d))
(A B C D)
[36]> (nthcdr 1 '(a b c d))
(B C D)
[37]> (nthcdr 2 '(a b c d))
(C D)
取第几个元素用nth,nthcdr是取第n个cdr,nth 等同于取 nthcdr 的 car。并且都是零索引。
Common Lisp 定义了函数 first 直到 tenth 可以取得列表对应的元素,但不是 零索引。
函数 last 返回列表的最后一个 Cons 对象。此外, Common Lisp 定义了像是 caddr 这样的函数,它是 cdr 的 cdr 的 car 的缩写 (car of cdr of cdr)。所有这样形式的函数 cxr ,其中 x 是一个字串,最多四个 a 或 d ,在 Common Lisp 里都被定义好了。
(defun our-atom (x) (not (consp x)))
上一篇: common lisp变量和赋值,类型判断
下一篇: common lisp列表学习2
0 Responses so far.