如何在elisp中的任意点退出函数

12

这是一个简单的问题,但我在谷歌上搜索时却找不到答案:

如果某个条件未满足,如何在函数的任意执行点退出函数。例如(我在此使用“(exit)”作为替代):

(defun foo ()
  (progn (if (/= a1 a2)
             (exit) ; if a1!=a2, exit the function somehow
           t)
         (blahblah...)))
4个回答

14
在elisp中,你可以使用catchthrow而不是使用cl的blockreturn-from
(defun foo ()
  (catch 'my-tag
    (when (not (/= a1 a2))
      (throw 'my-tag "non-local exit value"))
    "normal exit value"))

查看 C-hig (elisp) 非本地退出 RET


10

在函数体周围加上一个块,并从中返回:

(require 'cl-macs)
(defun foo ()
  (block foo
    (if (/= a1 a2)
        (return-from foo)
        reture-value))))

9

只需使用defun*代替defun(与cl包一起提供)。此宏已经像Common Lisp的defun一样运行(将函数体包装在try-catch块中,并将return-from别名为throw等)。

例如:

(require 'cl)

(defun* get-out-early ()
  "Get out early from this silly example."
  (when (not (boundp some-unbound-symbol))
    (return-from get-out-early))
  ;;
  ;; Get on with the func...
  ;;
  (do-such-and-such with-some-stuff))

3

一个函数返回最后一个被评估表单的值。如果你不关心这个值是什么,那么 nil 可能是一个合适的选择。在这种情况下,函数返回 if 函数的值。

例如:

(defun foo ()
  (if (/= a1 a2)
      nil
    "return-value"))

在这个简单的例子中,以下内容也是等价的:
(defun foo ()
  (if (not (/= a1 a2))
      "return-value"))

(defun foo ()
  (when (not (/= a1 a2))
    "return-value"))

这不是我的问题。抱歉,我的先前的例子有误导性。我已经更改了它。 - RNA
啊,好的。在大多数情况下,您应该能够构造代码以避免需要非本地退出的情况,但我已经添加了另一个答案,其中包含标准的Elisp方法来处理这个问题。 - phils

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接