# 11.3 条件组合结构（DONE）

本节介绍一些经常与if和cond协同使用，构造复杂条件的结构。其中结构 and 和 or可以单独作为条件结构使用。

\[Function] not condition

该函数测试condition是否为false类。若condition为nil，则返回t，否则返回nil。函数not和null是等价的，我们推荐你判断空列表时使用null。

\[Special Form] and conditions...

and特殊表达式会测试所有condition是否都为true。其工作的方式是对condition逐个求值。

求值过程中一旦出现某个condition求值为nil，那么理论上，余下condition不论求值结果，and必定都应返回nil；因此这时and会直接返回nil，并忽略后续条件的求值。

如果所有conditon的求值结果均为non-nil，那么最后一个condition的求值结果会作为整个and表达式的求值结果。无condition的单(and)表达式返回t，因为所有condition都是non-nil。

这里有个例子。第一个condition返回整数1，而非nil。类似的，第二个condition返回整数2，而非nil。紧接着第三个condition为nil，因此余下的condition将永远不会被求值。

<pre class="language-lisp"><code class="lang-lisp">(and (print 1) (print 2) nil (print 3))
<strong>    ⊣1
</strong>    ⊣2 
⇒ nil
</code></pre>

下面这个例子更加贴近现实：

```lisp
(if (and (consp foo) (eq (car foo) 'X))
    (message "foo is a list starting with X"))
```

需要注意的是，若(consp foo) 返回nil，那么(car foo)就不会执行，这样也就避免了一些错误。

and 表达式同样可以用if或cond组合出来：

```lisp
(and arg1 arg2 arg3)

(if arg1 (if arg2 arg3))

(cond (arg1 (cond (arg2 arg3))))
```

\[Special Form] or conditions...

or表达式用于测试conditions中是否至少有一个conditon求值为true。其工作方式为对conditon逐个求值。

若存在某个condition求值为non-nil，那么理论上，不论后续condition的求值结果，该or表达式都应返回t；因此此时or会直接返回t，而跳过余下condition的求值。

若所有condition的求值结果均为nil，那么该or表达式会返回nil。无condition的单(or)表达式会返回nil，因为所有的condition都为nil。

举个例子，下面的表达式测试了x是否为nil或整数0:

```lisp
(or (eq x nil) (eq x 0))
```

和 and 结构类似，or同样可以用cond组合出来：

```lisp
(or arg1 arg2 arg3)


(cond (arg1)
      (arg2)
      (arg3))
```

同样可以用if组合，但是会有点区别：

```lisp
(if arg1 arg1
  (if arg2 arg2
    arg3))
```

这个并不完全等价，因为arg1和arg2被求了两次值。相较之下，(or arg1 arg2 arg3)中任何参数求值次数不会超过1。

\[Function] xor condition1 condition2

该函数返回condition1和condition2的异或关系。也就是说，若两个参数的求值结果均为nil或non-nil，则返回nil。否则返回其中那个求值结果为non-nil的求值结果。

与or不同，xor中所有参数始终都会被求值。


---

# 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/kong-zhi-jie-gou/luo-ji-yun-suan.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.
