第11章 异常和状况

异常(exceptions)和状况(conditions)为系统和用户代码提供了发送信号、检测和从错误中恢复程序的方法。

标准语法形式和过程在一些情况下会引发异常,例如,当向过程传递错误数量的参数时,传递给eval的表达式的语法不正确,或者一个打开文件的过程无法打开文件时。在这些情况下,使用标准的状况类型引发异常。

用户代码也可以通过raiseraise-continuable过程来引发异常。在这种情况下,可以使用标准的状况类型,用户定义的标准状况类型的子类型(可以通过define-condition-type来定义),或者是状况类型之外的任意Scheme值。

在程序执行期间的任何时候,单个异常处理程序(称为current exception handler)负责处理所有引发的异常。默认情况下,当前异常处理程序通常会打印一条消息,该消息描述引发异常的状况或其它值,对于任何严重的状况,都会终止正在运行的程序。在交互式系统中,这通常意味着重置REPL(“读取-求值-打印 循环”)。

用户代码可以通过guard语法或with-exception-handler过程建立新的当前异常处理程序。在任何一种情况下,用户代码都可以处理所有异常,或者,基于引发异常的状况或其他值,只有一些异常,同时重新引用其他异常处理旧的当前异常处理程序。当动态嵌套保护形式和异常处理程序调用时,会建立一系列异常处理程序,每个异常处理程序都可以遵循链中的下一个。

1 引发和处理异常

procedure: (raise obj)

procedure: (raise-continuable obj)

returns: see below

libraries: (rnrs exceptions), (rnrs)

(raise
  (condition
    (make-error)
    (make-message-condition "no go"))) ; --> error: no go
(raise-continuable
  (condition
    (make-violation)
    (make-message-condition "oops"))) ; --> violation: oops
(list
  (call/cc
    (lambda (k)
      (vector
        (with-exception-handler
          (lambda (x) (k (+ x 5)))
          (lambda () (+ (raise 17) 8))))))) ; --> (22)
(list
  (vector
    (with-exception-handler
      (lambda (x) (+ x 5))
      (lambda () (+ (raise-continuable 17) 8))))) ; --> (#(30))
(list
  (vector
    (with-exception-handler
      (lambda (x) (+ x 5))
      (lambda () (+ (raise 17) 8))))) ; --> violation: non-continuable

results matching ""

    No results matching ""