如何在方案中实现try-catch块?

Asq*_*qan 8 error-handling scheme try-catch racket

我正在尝试使用(call-cc)方法在方案中实现try-catch块,但我不确定它是如何用于此的.我找不到任何例子.

并且发现示例只包含错误处理,但我想要做的是:如果发生错误,方案程序必须向用户发送消息(通过显示示例)而不挂起程序.

那可能吗?

Gre*_*ott 11

通常你会使用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
Run Code Online (Sandbox Code Playgroud)

如果你真的想因某种原因直接使用延续,你可以使用call/ec错误/转义延续而不是一般call/cc.

文档:

  • 您可以轻松编写一个使用`with-handlers`但看起来更像try-catch的宏:`(define-syntax try(syntax-rules(catch)[(_ e(catch [pred handle] ...))( with-handlers([pred handle] ...)e)]))` (3认同)

GoZ*_*ner 8

既然你想捕获所有的错误,如双方提出的那些raiseraise-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)))))))
Run Code Online (Sandbox Code Playgroud)

这被用作例如:

> (try (begin (display "one\n")
              (raise 'some-error)
              (display "two\n"))
    (catch (display "error\n")))
one
error
some-error       # the return value.
Run Code Online (Sandbox Code Playgroud)

注意:这是R6RS(和R7RS)计划.