# 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中所有参数始终都会被求值。
