4

使用 ELisp 时,如何在语句else块中执行多个表达式?if

4

2 回答 2

12

您不需要这样做progn,因为这已经是默认行为:

C-hf if RET

if 是“C 源代码”中的一种特殊形式。

(如果条件那么其他......)

如果 COND 产生非零,则执行 THEN,否则执行 ELSE...
返回 THEN 的值或最后一个 ELSE 的值。
THEN 必须是一个表达式,但 ELSE... 可以是零个或多个表达式。
如果 COND 产生 nil,并且没有 ELSE,则值为 nil。

重用 sindikat 的例子:

(if (> 1 2)
    (message "True")
  (message "False")
  (message "I repeat, completely false"))

当然,progn如果您希望计算THEN表单中的多个表达式,则可以使用。

于 2012-04-26T12:17:31.623 回答
5

菲尔斯的回答是正确且惯用的。如果您想在 的else块中执行多个语句if,并且您只关心 Emacs Lisp,请按照他的答案进行。

在 Emacs Lisp 和 Common Lisp 中,当您想按顺序执行多个操作以产生副作用时(例如更改变量、在屏幕上打印某些内容,通常是与函数返回值无关的任何操作),然后返回只有一个表达式,您使用progn, prog1, 或prog2。它们都计算其中的所有表单,但分别只返回最后一个、第一个和第二个表达式的值。

(progn 1 2 3 4 5)返回 5,(prog1 1 2 3 4 5)返回 1,(prog2 1 2 3 4 5)返回 2。这显然是没有用的,因为在progn, prog1,中评估表单prog2的目的是为了产生副作用。因此,以下所有内容都会在回显区域(和缓冲区)中打印 string α, β, γ, ,但只会返回其中一个字符串:δ*Messages*

(progn (message "α") (message "β") (message "γ") (message "δ")) ; => "δ"
(prog1 (message "α") (message "β") (message "γ") (message "δ")) ; => "α"
(prog2 (message "α") (message "β") (message "γ") (message "δ")) ; => "β"

所有 3 个函数都存在于 Emacs Lisp 和 Common Lisp 中。但是如果你想返回第三个表达式的值呢?没有prog3。结合现有的!以下所有返回γ

(progn (message "α") (message "β") (prog1 (message "γ") (message "δ"))) ; => "γ"
(prog1 (progn (message "α") (message "β") (message "γ")) (message "δ")) ; => "γ"
(prog2 (message "α") (progn (message "β") (message "γ")) (message "δ")) ; => "γ"
(prog2 (message "α") (prog2 (message "β") (message "γ") (message "δ"))) ; => "γ"

在 Common Lisp 中将语句组合在一起并仅返回最后一个值 in if,您可以:

(if t
    (progn (message "ε") (message "ζ"))
    (progn (message "η") (message "θ"))) ; returns ζ
(if nil
    (progn (message "ε") (message "ζ"))
    (progn (message "η") (message "θ"))) ; returns θ

在 Emacs Lisp 中,您仍然必须将语句thenprogn, prog1,组合在一起prog2,但您else不必在块中这样做,因此 phils 的回答。在 Emacs Lisp(if nil 1 2 3)中会返回 3,而在 Common Lisp 中会出错too many parameters for special operator IF

另请参阅:“ Emacs Lisp Intro ”中的“8.1.4 'progn' 特殊形式”部分。

于 2012-04-26T09:38:01.107 回答