条件构造

在 Common Lisp 中,if 是最简单的条件构造。它具有 (if test then [else]) 的形式,如果 test 为真,则评估为 then,否则评估为 else。else 部分可以省略。

(if (> 3 2)
    "Three is bigger!"
    "Two is bigger!")
;;=> "Three is bigger!"

Common Lisp 中的 if 和许多其他编程语言中的 if 之间的一个非常重要的区别是 CL 的 if 是一个表达式,而不是一个语句。因此,if 形成返回值,可以将其分配给变量,在参数列表中使用等:

;; Use a different format string depending on the type of x
(format t (if (numberp x)
              "~x~%"
              "~a~%")
           x)

Common Lisp 的 if 可以被认为等同于三元运算符?: 在 C#和其他大括号语言中。

例如,以下 C#表达式:

year == 1990 ? "Hammertime" : "Not Hammertime"

等效于以下 Common Lisp 代码,假设 year 包含一个整数:

(if (eql year 1990) "Hammertime" "Not Hammertime")

cond 是另一个条件结构。它有点类似于 if 语句链,并具有以下形式:

(cond (test-1 consequent-1-1 consequent-2-1 ...)
      (test-2)
      (test-3 consequent-3-1 ...)
      ... )

更准确地说,cond 有零个或多个子句,每个子句有一个测试,后跟零个或多个结果。整个 cond 构造选择第一个子句,其测试不评估为 nil 并按顺序评估其结果。它返回结果中最后一个表单的值。

(cond ((> 3 4) "Three is bigger than four!")
      ((> 3 3) "Three is bigger than three!")
      ((> 3 2) "Three is bigger than two!")
      ((> 3 1) "Three is bigger than one!"))
;;=> "Three is bigger than two!"

要提供一个 default 子句来评估是否有其他子句的计算结果为 t,你可以使用 t 添加一个默认为 true 的子句。这在概念上与 SQL 的 CASE...ELSE 非常相似,但它使用文字布尔值而不是关键字来完成任务。

(cond
    ((= n 1) "N equals 1")
    (t "N doesn't equal 1")
)

if 构造可以写成 cond 构造。(if test then else)(cond (test then) (t else)) 是等价的。

如果你只需要一个子句,请使用 whenunless

(when (> 3 4)
  "Three is bigger than four.")
;;=> NIL

(when (< 2 5)
  "Two is smaller than five.")
;;=> "Two is smaller than five."

(unless (> 3 4)
  "Three is bigger than four.")
;;=> "Three is bigger than four."

(unless (< 2 5)
  "Two is smaller than five.")
;;=> NIL