Wie können Sie frühzeitig von einer Funktion zurückkehren, bevor sie beendet ist? Beispielsweise:
(defun my-func ()
"for example."
(unless something (return nil))
; continue as usual...
(+ 42 1))
Wir haben eine Reihe von Optionen zur Verfügung.
Sie können catch
/ throw
die Funktion zu verlassen.
Beispiel:
(defun my-func ()
"thrown error"
(catch 'my-catch
(when t
(throw 'my-catch "always going to throw"))
(+ 42 1)))
Sie können auch block
und verwenden return-from
(obwohl Sie benötigen cl-macs
)
Beispiel:
(require 'cl-macs)
(defun my-func ()
"block / return-from"
(block my-func
(when t
(return-from my-func))
(+ 42 1)))
Wir haben cl-defun
auch ein implizites Element block
mit demselben Namen wie die Funktion, sodass wir den block
Stil mit weniger ausführen können .
Beispiel:
(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
ist auch als Alias verfügbar, defun*
der folgendermaßen definiert ist 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
in elisp idiomatischer ist , wenn Sie die CL-Syntax nicht bevorzugen , da andere Ansätze letztendlich in Bezug auf catch / throw implementiert werden. Die elisp Handbuch sagt: „ Die meisten anderen Versionen von Lisp, einschließlich Common Lisp, haben mehrere Möglichkeiten der Steuerung übertragen nonsequentially:return
,return-from
, undgo
., Zum Beispiel Emacs Lisp hat nurthrow
.“Zusätzlich zu dem, was @EmacsFodder behandelt, wird nur ein Fehler gemeldet.
Dies ist nicht hilfreich, wenn der Code innerhalb des Umfangs von Fehlerbehandlungskonstrukten wie
ignore-errors
oder (dynamisch, nicht lexikalisch) aufgerufen wird.condition-case
Andernfalls ist dies eine gute Möglichkeit, eine Funktion zu beenden. Es ist in der Tat, was die meiste Zeit getan wird.Wenn Sie den Fehler selbst behandeln möchten, können Sie den aufrufenden Code (z. B. den Anruf an etwas, das letztendlich aufruft
my-func
) in a einfügencondition-case
. Wiederum wird dies die meiste Zeit getan, mindestens so oft wie mitcatch
+throw
. Es hängt alles davon ab, welches Verhalten Sie wollen.quelle
catch
, sindunwind-protect
,condition-case
und dergleichen nützlich. Es gibt einen ganzen Abschnitt des Elisp-Handbuchs, der sich mit nichtlokalen Ausgängen befasst . (Und es gibt nichts besonders kludiges an einem von ihnen, IMO.)