3.2 等式 (Equality)

每一次你调用 cons 时, Lisp 会配置一块新的内存给两个指针。所以如果我们用同样的参数调用 cons 两次,我们得到两个数值看起来一样,但实际上是两个不同的对象:

  1. > (eql (cons 'a nil) (cons 'a nil))
  2. NIL

如果我们也可以询问两个列表是否有相同元素,那就很方便了。 Common Lisp 提供了这种目的另一个判断式: equal 。而另一方面 eql 只有在它的参数是相同对象时才返回真,

  1. > (setf x (cons 'a nil))
  2. (A)
  3. > (eql x x)
  4. T

本质上 equal 若它的参数打印出的值相同时,返回真:

  1. > (equal x (cons 'a nil))
  2. T

这个判断式对非列表结构的别种对象也有效,但一种仅对列表有效的版本可以这样定义:

  1. > (defun our-equal (x y)
  2. (or (eql x y)
  3. (and (consp x)
  4. (consp y)
  5. (our-equal (car x) (car y))
  6. (our-equal (cdr x) (cdr y)))))

这个定义意味着,如果某个 xy 相等( eql ),那么他们也相等( equal )。

勘误: 这个版本的 our-equal 可以用在符号的列表 (list of symbols),而不是列表 (list)。