Відповіді:
У нас є ряд варіантів.
Ви можете 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) всередині condition-case. Знову ж таки, це робиться більшість часу, принаймні так часто, як використання catch+ throw. Все залежить від того, якої поведінки ви хочете.
catch, unwind-protect, condition-caseі т.п. корисні. Є цілий розділ посібника Елісп, присвячений нелокальним виходам . (І нічого з цього немає, особливо IMO.)
catch/throwє більш ідіоматичним в elisp, оскільки інші підходи в кінцевому рахунку реалізуються з точки зору лову / кидання. Elisp керівництво каже: «Більшість інших версій Lisp, включаючи Common Lisp, є кілька способів передачі управління nonsequentially:return,return-from, іgo., Наприклад , Emacs Lisp має тількиthrow.»