Как вы рано вернетесь из функции до ее завершения? Например:
(defun my-func ()
"for example."
(unless something (return nil))
; continue as usual...
(+ 42 1))
У нас есть несколько вариантов.
Вы можете catch
/, throw
чтобы выйти из функции.
пример:
(defun my-func ()
"thrown error"
(catch 'my-catch
(when t
(throw 'my-catch "always going to throw"))
(+ 42 1)))
Вы также можете использовать block
и return-from
(хотя вам потребуется cl-macs
)
пример:
(require 'cl-macs)
(defun my-func ()
"block / return-from"
(block my-func
(when t
(return-from my-func))
(+ 42 1)))
У нас также cl-defun
есть неявное имя block
с тем же именем, что и у функции, поэтому мы можем делать block
стиль с меньшими затратами.
пример:
(require 'cl-macs)
(cl-defun my-func ()
"cl-defun implicit block"
(when t
(return-from my-func)) ; my-func is an implicit block.
(+ 42 1)))
cl-defun
также доступен как псевдоним, defun*
который определен cl.el
так:
(require 'cl)
(defun* my-func ()
"defun* implicit block"
(when t
(return-from my-func)) ; my-func is an implicit block.
(+ 42 1)))
catch
/throw
является более идиоматичным в elisp, так как другие подходы в конечном итоге реализованы в терминах catch / throw. Elisp руководство говорит: «Большинство других версий Lisp, включая Common Lisp, есть несколько способов передачи управления nonsequentially:return
,return-from
, иgo
., Например , Emacs Lisp имеет толькоthrow
.»В дополнение к тому, что описано в @EmacsFodder, просто выдайте ошибку.
Это не поможет, если код вызывается внутри (динамически, а не лексически) степени конструкций обработки ошибок, таких как
ignore-errors
илиcondition-case
, но в противном случае это хороший способ выхода из функции. Это на самом деле то, что делается большую часть времени.Если вы хотите обработать ошибку самостоятельно, вы можете поместить вызывающий код (например, вызов чего-то, что вызывает неожиданно
my-func
) внутри acondition-case
. Опять же, это то, что делается в большинстве случаев, по крайней мере, так же часто, как с помощьюcatch
+throw
. Все зависит от того, какое поведение вы хотите.источник
catch
,unwind-protect
,condition-case
и т.п. полезны. Существует целый раздел руководства Elisp, посвященный нелокальным выходам . (И в них нет ничего особенно глупого, IMO.)