我試圖在使用(call-cc)方法的方案中實現try-catch塊,但我不確定如何使用它。我找不到任何例子。如何在方案中實現try-catch塊?
而發現的例子只包含錯誤處理,但我想做的事是:如果發生錯誤,該方案計劃已經給消息給用戶(通過顯示器,例如)不暫停程序。
這可能嗎?
我試圖在使用(call-cc)方法的方案中實現try-catch塊,但我不確定如何使用它。我找不到任何例子。如何在方案中實現try-catch塊?
而發現的例子只包含錯誤處理,但我想做的事是:如果發生錯誤,該方案計劃已經給消息給用戶(通過顯示器,例如)不暫停程序。
這可能嗎?
既然你想捕獲所有的錯誤,如雙方raise
提出的人與raise-continuable
你需要一個都異常處理程序(處理引發的條件)和退出延續(以避免繼續使用try
身體)。對於try
簡單的語法是:
(import (rnrs base) ; define-syntax
(rnrs exceptions)) ; get `with-exception-handler`
(define-syntax try
(syntax-rules (catch)
((_ body (catch catcher))
(call-with-current-continuation
(lambda (exit)
(with-exception-handler
(lambda (condition)
catcher
(exit condition))
(lambda() body)))))))
這被使用,例如:
> (try (begin (display "one\n")
(raise 'some-error)
(display "two\n"))
(catch (display "error\n")))
one
error
some-error # the return value.
注:這是R6RS(和R7RS)計劃。
通常您會使用with-handlers
表單。這可讓您在返回值之前顯示錯誤消息或執行任何其他操作。
#lang racket
(define (foo x)
(with-handlers ([exn:fail? (lambda (exn)
(displayln (exn-message exn))
#f)])
(/ 1 x)))
(foo 1)
; 1
(foo 0)
; "/: division by zero"
; #f
如果你真的想要直接使用延續出於某種原因,你可以使用call/ec
的錯誤/逃生延續,而不是一般call/cc
。
文檔:
try-catch更清晰可理解但這種異常處理方式似乎更方便;我會用這個我想:)謝謝你的答案! – Asqan 2013-05-11 03:45:14
你可以很容易地編寫一個使用'with-handlers'的宏,但看起來更像try-catch:'(define-syntax try(syntax-rules(catch)[(_e(catch [pred handle] ...)) (with-handlers([pred handle] ...)e)]))' – 2013-05-11 14:18:52
謝謝你的回答!這就是我一直在尋找的,但'帶異常處理程序無法找到。也在球拍和r6rs。 – Asqan 2013-05-11 03:39:55
嗯,我在Ikarus中運行代碼...在(rnrs exceptions)庫中找到'with-exceptions-handler'。查看更新的答案。請參閱第7.1節,第24頁或R6RS-Lib文檔。 – GoZoner 2013-05-11 03:41:01
謝謝!這裏(http://docs.racket-lang.org/r6rs/)是你如何在球拍中使用(例外)。 – GoZoner 2013-05-11 03:47:32