# 11.2 条件判断（DONE）

条件控制结构会在众多的选项中做选择。Emacs Lisp中包含5种条件表达式：if（和绝大多数其他语言中的类似）；when和unless（这些为if的变体）；cond（更通用的条件表达式）；以及pcase（更通用的cond）。

\[Special Form] if condition then-form else-forms...

if 会基于condition的求值结果，选择对then-form求值还是对else-forms求值。若condition的求值结果为non-nil，那么会对then-form求值，并将其求值结果返回。否则，将会依次对else-forms中的表达式进行求值，并返回其最后一个表达式的求值结果。（if的else部分被隐式实现了progn）

若condition求值为nil，并且未提供else-forms，那么返回nil。

if 是一个特殊表达式，其中没有被选择的分支将不会被求值。因此在下面这个例子里，true将不会被打印，因为print根本就不会被调用：

```lisp
(if nil
    (print 'true)
    'very-false)
=>   very-falses
```

\[Macro] when condition then-forms...

这是if的一个变体，该变体中不包含else-forms，但可以包含若干then-forms。

特别的，

```lisp
(when condition a b c)
```

和下面完全等价

```lisp
(if condition (progn a b c) nil)
```

\[Macro] unless condition forms...

这是if的一个变体，该变体中不包含then-from：

```lisp
(unless condition a b c)
```

和下面完全等价

```lisp
(if condition nil
    a b c)
```

\[Specila Form] cond clause...

cond会在任意数量的分支中做出选择。cond中每个clause都必须是一个列表。该列表的car部分为condition而余下的部分均为表达式体body-forms。也就是说，一个clause看起来像这样：

```lisp
(condition body-forms...)
```

cond会依次尝试测试每个clause中的condition，直到某个condition求值为non-nil；然后cond会对对应clause的body-forms进行求值，并将其中最后一个表达式的求值结果作为整体的求值结果。任何余下的clause都会被忽略。

clause同样可以类似这样：

```lisp
(condition)
```

此时若condition求值为non-nil，那么cond表达式会将该值作为结果返回。

若每个condition求值均为nil，也就是所有的clause测试都未通过，那么cond会返回nil。

下面这个例子中有4个clause，其中每个clause分别测试x是否是数字、字符串、缓冲区以及符号：

```lisp
(cond ((numberp x) x)
      ((stringp x) x)
      ((bufferp x)
       (setq temporary-hack x)
       (buffer-name x))
      ((symbolp x) (symbol-value x)))
```

通常我们想在最后设置一个默认clause，当前面所有的clause都未通过测试时求值。此时我们可以将t作为该clause的condition，就像这样(t body-forms)。表达式t求值后得到t，永远通过测试，因此该clause永远不会失败。举个例子：

```lisp
(setq a 5)
(cond ((eq a 'hack) 'foo)
      (t "default"))
=>  "default"
```

若a求值结果为hack，则返回foo，否则返回字符串"default"。

任何条件结构都可以使用cond或if组合出来。因此，使用哪一个仅仅是风格问题。比如下面两个就是等价的：

```lisp
(if a b c)

(cond (a b) (t c))
```
