使用 ELisp 时,如何在语句else
块中执行多个表达式?if
2 回答
您不需要这样做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
表单中的多个表达式,则可以使用。
菲尔斯的回答是正确且惯用的。如果您想在 的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 中,您仍然必须将语句then
与progn
, 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' 特殊形式”部分。