2.8 相等谓语

这里我们描述测试两个对象之间相等性的函数。其他函数测试特定类型对象(例如字符串)之间内容的相等性。对于这些谓词,请参阅描述数据类型的相应章节。

Function: eq object1 object2

如果object1和object2是同一个对象,则此函数返回t,否则返回nil

如果object1和object2是同名的符号,它们通常是同一个对象——但请参阅创建符号以了解例外情况。对于其他非数字类型(例如,列表、向量、字符串),具有相同内容或元素的两个参数不一定相互eq:当且仅当它们是同一个对象时,它们才eq,这意味着其中一个对象的内容发生变化时,相同的变化会体现在另一个对象的内容上。

如果object1和object2是具有不同类型或值的数字,则它们不可能是同一个对象,返回nil。如果它们是具有相同值的 fixnum,则它们是相同的对象并返回t。如果它们是单独计算的,但碰巧具有相同的值和相同的数字类型,那么它们可能是也可能不是同一个对象,返回tnil 取决于 Lisp 解释器创建了一个还是两个对象。

(eq 'foo 'foo)
     ⇒ t

(eq ?A ?A)
     ⇒ t

(eq 3.0 3.0)
     ⇒ t or nil
;; Equal floats may or may not be the same object.

(eq (make-string 3 ?A) (make-string 3 ?A))
     ⇒ nil

(eq "asdf" "asdf")
     ⇒ t or nil
;; Equal string constants or may not be the same object.

(eq '(1 (2 (3))) '(1 (2 (3))))
     ⇒ nil

(setq foo '(1 (2 (3))))
     ⇒ (1 (2 (3)))
(eq foo foo)
     ⇒ t
(eq foo '(1 (2 (3))))
     ⇒ nil

(eq [(1 2) 3] [(1 2) 3])
     ⇒ nil

(eq (point-marker) (point-marker))
     ⇒ nil

make-symbol函数返回一个未收录符号,与在 Lisp 表达式中写入名称时使用的符号不同。此时具有相同名称的不同符号并不eq。请参阅创建符号

(eq (make-symbol "foo") 'foo)
     ⇒ nil

Emacs Lisp 字节编译器可能会将相同的文字对象(例如文字字符串)折叠为对同一对象的引用,但解释器可能并不会这么做。因此,你的代码永远不要使用 eq 去比较两者的文本意义,你应该使用 equal 函数去比较文本意义。

Function: equal object1 object2

如果object1和object2具有相同的组件,则此函数返回t,否则返回nileq测试它的参数是否是同一个对象,而equal查看不相同参数的元素或内容是否相同。因此,如果两个对象是eq,则它们是equal,但反过来并不总是正确的。

(equal 'foo 'foo)
     ⇒ t

(equal 456 456)
     ⇒ t

(equal "asdf" "asdf")
     ⇒ t
(eq "asdf" "asdf")
     ⇒ nil

(equal '(1 (2 (3))) '(1 (2 (3))))
     ⇒ t
(eq '(1 (2 (3))) '(1 (2 (3))))
     ⇒ nil

(equal [(1 2) 3] [(1 2) 3])
     ⇒ t
(eq [(1 2) 3] [(1 2) 3])
     ⇒ nil

(equal (point-marker) (point-marker))
     ⇒ t

(eq (point-marker) (point-marker))
     ⇒ nil

字符串的比较区分大小写,但不考虑文本属性——它只比较字符串中的字符。请参阅文本属性。使用equal-including-properties也比较文本属性。出于技术原因,当且仅当单字节字符串和多字节字符串包含相同的字符代码序列,并且所有这些代码都在 0 到 127 ( ASCII )范围内时,它们才equal

(equal "asdf" "ASDF")
     ⇒ nil

但是,两个不同的缓冲区从不equal,即使它们的文本内容相同。

对于equal,相等是递归定义的;例如,给定两个节点X和Y, 当且仅当下面两个表达式同时返回t时返回t

(equal (car x) (car y))
(equal (cdr x) (cdr y))

因此,比较循环列表可能会导致导致错误的深度递归,这可能会导致违反直觉的行为,例如 (equal a b)返回t(equal b a) 发出错误信号。

Function: equal-including-propertied object1 object2

此函数在所有情况下的行为都类似equal,但此外,若要求两个字符串相等,那么它们具有的文本属性也必须相同。

(equal "asdf" (propertize "asdf" 'asdf t))
     ⇒ t
(equal-including-properties "asdf"
                            (propertize "asdf" 'asdf t))
     ⇒ nil

最后更新于