使用ELisp时,如何在else
语句的if
块中执行多个表达式?
答案 0 :(得分:10)
您不需要progn
,因为这已经是默认行为:
C-h f if
RET
如果是“C源代码”中的特殊形式。
(如果COND那么......)
如果COND产生非零,那么那么,否则做ELSE ...
返回THEN的值或ELSE的最后一个值。
那么必须是一个表达式,但ELSE ...可以是零个或多个表达式。
如果COND产生nil,并且没有ELSE,则值为nil。
重新使用sindikat的例子:
(if (> 1 2)
(message "True")
(message "False")
(message "I repeat, completely false"))
如果您希望以progn
形式评估多个表达式,您当然会使用THEN
。
答案 1 :(得分:4)
phils's answer是正确和惯用的。如果你想在else
的{{1}}块中执行多个语句,而你只关心Emacs Lisp,那么请回答他的问题。
在Emacs Lisp和Common Lisp中,当你想按顺序为side effects执行多个动作时(比如更改变量,在屏幕上打印一些东西,通常,任何与函数返回值无关的东西),然后返回其中一个表达式的值,使用progn
,prog1
或prog2
。它们都评估它们内部的所有形式,但分别只返回last,first和second表达式的值。
if
返回5,(progn 1 2 3 4 5)
返回1,(prog1 1 2 3 4 5)
返回2.这显然无用,因为评估(prog2 1 2 3 4 5)
,progn
中的表单的重点,prog1
用于副作用。因此,以下所有内容都会在echo area(以及*Messages*
缓冲区)中打印字符串prog2
,α
,β
,γ
,但仅限于其中一个字符串将被返回:
δ
所有3个函数都存在于Emacs Lisp和Common Lisp中。但是如果你想返回3 rd 表达式的值呢?没有(progn (message "α") (message "β") (message "γ") (message "δ")) ; => "δ"
(prog1 (message "α") (message "β") (message "γ") (message "δ")) ; => "α"
(prog2 (message "α") (message "β") (message "γ") (message "δ")) ; => "β"
。结合现有的!以下所有内容都会返回prog3
:
γ
在Common Lisp中将语句组合在一起并仅返回(progn (message "α") (message "β") (prog1 (message "γ") (message "δ"))) ; => "γ"
(prog1 (progn (message "α") (message "β") (message "γ")) (message "δ")) ; => "γ"
(prog2 (message "α") (progn (message "β") (message "γ")) (message "δ")) ; => "γ"
(prog2 (message "α") (prog2 (message "β") (message "γ") (message "δ"))) ; => "γ"
中最后一个语句的值,您可以这样做:
if
在Emacs Lisp中,您仍需要(if t
(progn (message "ε") (message "ζ"))
(progn (message "η") (message "θ"))) ; returns ζ
(if nil
(progn (message "ε") (message "ζ"))
(progn (message "η") (message "θ"))) ; returns θ
阻止then
,progn
,prog1
,但prog2
阻止你“因此,phils的回答。在Emacs中,Lisp else
将返回3,而在Common Lisp中,它将与(if nil 1 2 3)
错误。
另请参阅:“8.1.4 The 'progn' Special Form”中的“Emacs Lisp Intro”部分。