# 2.8 相等谓语

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

Function: **eq** *object1 object2*

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

如果object1和object2是同名的符号，它们通常是同一个对象——但请参阅[创建符号](https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html)以了解例外情况。对于其他非数字类型（例如，列表、向量、字符串），具有相同内容或元素的两个参数不一定相互`eq`：当且仅当它们是同一个对象时，它们才`eq`，这意味着其中一个对象的内容发生变化时，相同的变化会体现在另一个对象的内容上。

如果object1和object2是具有不同类型或值的数字，则它们不可能是同一个对象，返回`nil`。如果它们是具有相同值的 fixnum，则它们是相同的对象并返回`t`。如果它们是单独计算的，但碰巧具有相同的值和相同的数字类型，那么它们可能是也可能不是同一个对象，返回`t`或`nil` 取决于 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`。请参阅[创建符号](https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html)。

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

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

Function: equal object1 object2

如果object1和object2具有相同的组件，则此函数返回`t`，否则返回`nil`。`eq`测试它的参数是否是同一个对象，而`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
```

字符串的比较区分大小写，但不考虑文本属性——它只比较字符串中的字符。请参阅[文本属性](https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Properties.html)。使用`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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://emacs-lisp.ivory.cafe/lisp-shu-ju-lei-xing/2.8-xiang-deng-wei-yu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
