处理条件
让我们举一个处理由被零除条件引起的条件的例子来解释这里的概念。
您需要采取以下步骤来处理条件 -
(define-condition condition-name (error)
((text :initarg :text :reader text))
)
在我们的示例中,以下代码定义了条件 -
(define-condition on-division-by-zero (error)
((message :initarg :message :reader message))
)
-
Writing the Handlers− 条件处理程序是用于处理在其上发出信号的条件的代码。它通常写在调用错误函数的高级函数之一中。当发出条件信号时,信号机制会根据条件的类搜索合适的处理程序。
每个处理程序包括 -
- 类型说明符,指示它可以处理的条件类型
- 接受单个参数的函数,即条件
当发出条件信号时,信号机制会找到最近建立的与条件类型兼容的处理程序并调用其函数。
宏观handler-case建立一个条件处理器。处理程序案例的基本形式 -
(handler-case expression error-clause*)
其中,每个错误条款的形式为 -
condition-type ([var]) code)
(handler-bind (binding*) form*)
每个绑定都是以下列表 -
这invoke-restart宏以指定名称作为参数查找并调用最近绑定的重启函数。
您可以多次重新启动。
例子
在这个例子中,我们通过编写一个名为 division-function 的函数来演示上述概念,如果除数参数为零,它将创建一个错误条件。我们有三个匿名函数,它们提供了三种方法 - 返回值 1,发送除数 2 并重新计算,或返回 1。
创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。
(define-condition on-division-by-zero (error)
((message :initarg :message :reader message))
)
(defun handle-infinity ()
(restart-case
(let ((result 0))
(setf result (division-function 10 0))
(format t "Value: ~a~%" result)
)
(just-continue () nil)
)
)
(defun division-function (value1 value2)
(restart-case
(if (/= value2 0)
(/ value1 value2)
(error 'on-division-by-zero :message "denominator is zero")
)
(return-zero () 0)
(return-value (r) r)
(recalc-using (d) (division-function value1 d))
)
)
(defun high-level-code ()
(handler-bind
(
(on-division-by-zero
#'(lambda (c)
(format t "error signaled: ~a~%" (message c))
(invoke-restart 'return-zero)
)
)
(handle-infinity)
)
)
)
(handler-bind
(
(on-division-by-zero
#'(lambda (c)
(format t "error signaled: ~a~%" (message c))
(invoke-restart 'return-value 1)
)
)
)
(handle-infinity)
)
(handler-bind
(
(on-division-by-zero
#'(lambda (c)
(format t "error signaled: ~a~%" (message c))
(invoke-restart 'recalc-using 2)
)
)
)
(handle-infinity)
)
(handler-bind
(
(on-division-by-zero
#'(lambda (c)
(format t "error signaled: ~a~%" (message c))
(invoke-restart 'just-continue)
)
)
)
(handle-infinity)
)
(format t "Done."))
当您执行代码时,它返回以下结果 -
error signaled: denominator is zero
Value: 1
error signaled: denominator is zero
Value: 5
error signaled: denominator is zero
Done.
除了上面讨论的“条件系统”之外,Common LISP 还提供了各种函数,可以调用这些函数来发出错误信号。然而,当发出错误信号时,错误的处理是依赖于实现的。