if 表达式可以带有一个可选的第三个参数,称为
否则部分(else-part),用于真假判断返回假的情况。
当判断为假时,整个 if 表达式的第二个参数(即那么部分)
不会 被求值,而第三个参数(否则部分) 会 被求值。
你可以把它理解为阴天版的决策:“如果天气温暖晴朗,就去海边,
否则就在家看书!”。
Lisp 代码中并不会写出单词“else”;if 表达式的否则部分
直接写在那么部分之后。在 Lisp 代码书写中,否则部分通常
单独起一行,缩进比那么部分更少:
(if true-or-false-test
action-to-carry-out-if-the-test-returns-true
action-to-carry-out-if-the-test-returns-false)
例如,下面的 if 表达式按常规方式求值时,
会打印消息 ‘4 is not greater than 5!’:
(if (> 4 5) ; if-part (message "4 falsely greater than 5!") ; then-part (message "4 is not greater than 5!")) ; else-part
可以看到,不同层级的缩进让那么部分和否则部分很容易区分。
(GNU Emacs 提供了多个命令,可以自动为 if 表达式正确缩进。
See GNU Emacs Helps You Type Lists。)
我们可以扩展 type-of-animal 函数,
只需在 if 表达式中增加一个部分,即可加入否则分支。
你可以对下面这个版本的 type-of-animal 函数定义求值以安装它,
然后对后续两个表达式求值,传入不同参数,就能看到效果。
(defun type-of-animal (characteristic) ; Second version.
"Print message in echo area depending on CHARACTERISTIC.
If the CHARACTERISTIC is the string \"fierce\",
then warn of a tiger; else say it is not fierce."
(if (equal characteristic "fierce")
(message "It is a tiger!")
(message "It is not fierce!")))
(type-of-animal "fierce") (type-of-animal "striped")
对 (type-of-animal "fierce") 求值时,回显区会打印:
"It is a tiger!";而对 (type-of-animal "striped")
求值时,会打印 "It is not fierce!"。
(当然,如果 characteristic 是 "ferocious",
同样会打印 "It is not fierce!",这就会产生误导!
编写代码时,需要考虑到 if 可能会测试到这类参数,
并相应地设计程序。)