Wie funktioniert PLTScheme Fangfehler?
-
21-09-2019 - |
Frage
Ich bin von dem „Fehler“ -Funktion in PLTScheme erstaunt. Wenn ich eine Division durch Null habe, tut es andere Rekursion tun und kommt nur von dem Call-Stack aus und geben Sie mir einen Fehler.
Gibt es eine implizite Fortsetzung vor allen Funktionen? Wirft der Fehler den Call-Stack weg? Hat jemand dies eine Ahnung haben?
Lösung
In PLT Scheme, das Verfahren Fehler hebt die Ausnahme EXN: fail , die einen Fehler enthält Zeichenfolge. Es gibt keinen „impliziten Fang“ für alle definiert. Blick auf die folgenden Beispiel:
;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
Führen Sie das Skript von der Kommandozeile und Sie werden die Interpreter bestehende nach dem Druck etwas wie
siehe/: division by zero
=== context ===
/home/user/test.ss:1:0: a
Wenn eine Ausnahme nicht innerhalb des Anwenderprogramms behandelt wird, wird es auf den Kern-Interpreter nach oben weitergegeben, wo ein Standard-Handler behandelt, ausdrucken das heißt die Ausnahme und beenden. Mit anderen Worten, sagt der Dolmetscher nur „eine Ausnahme ausgelöst wurde, und ich weiß nicht, wie sie damit umgehen, also bin ich quiting“. Das ist nicht viel anders aus, wie die JVM oder eine andere virtuelle Maschine Griff Ausnahmen.
Weitere Informationen über PLT Scheme Ausnahmebehandlung Mechanismus Um zu erfahren, lesen Sie über mit Zufuhren und dynamic-Wind in MzScheme Sprache Handbuch . Mit diesen können Sie auch emulieren Java Try-Catch-finally-Block.
(define (d a b)
(try
(printf "~a~n" (/ a b))
(catch (lambda (ex)
(printf "Error: ~a" ex)))
(finally
(if (> b -2)
(d a (sub1 b))))))
Hier ist die Syntax-Erweiterung, die die oben möglich gemacht hat:
;; try-catch-finally on top of with-handlers and dynamic-wind.
(define-syntax try
(syntax-rules (catch finally)
((_ try-body ... (catch catch-proc))
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
((_ try-body ... (catch catch-proc) (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda ()
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
(lambda () fin-body ...)))
((_ try-body ... (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda () try-body ...)
(lambda () fin-body ...)))))