Ответы:
У нас есть несколько вариантов.
Вы можете 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)))
В дополнение к тому, что описано в @EmacsFodder, просто выдайте ошибку.
Это не поможет, если код вызывается внутри (динамически, а не лексически) степени конструкций обработки ошибок, таких как ignore-errors
или condition-case
, но в противном случае это хороший способ выхода из функции. Это на самом деле то, что делается большую часть времени.
(defun my-func ()
"..."
(unless something (error "Whoops!"))
; continue as usual...
(+ 42 1))
Если вы хотите обработать ошибку самостоятельно, вы можете поместить вызывающий код (например, вызов чего-то, что вызывает неожиданно my-func
) внутри a condition-case
. Опять же, это то, что делается в большинстве случаев, по крайней мере, так же часто, как с помощью catch
+ throw
. Все зависит от того, какое поведение вы хотите.
catch
, unwind-protect
, condition-case
и т.п. полезны. Существует целый раздел руководства Elisp, посвященный нелокальным выходам . (И в них нет ничего особенно глупого, IMO.)
catch
/throw
является более идиоматичным в elisp, так как другие подходы в конечном итоге реализованы в терминах catch / throw. Elisp руководство говорит: «Большинство других версий Lisp, включая Common Lisp, есть несколько способов передачи управления nonsequentially:return
,return-from
, иgo
., Например , Emacs Lisp имеет толькоthrow
.»