(如何)处理程序可以设置信号函数的 return 值?
(How) can a handler set the return value of signal function?
从SBCL的文档中,我们可以了解到:
Invokes the signal facility on a condition formed from DATUM and
ARGUMENTS. If the condition is not handled, NIL is returned.
它没有详细说明在处理条件的情况下 signal
return 是什么。
因此,我假设(猜测)处理程序可以以某种方式确定信号函数的 return 值:
(defun countdown (&optional
(start-value 10)
(fail-value 1))
(loop
repeat start-value
for i from 0
collecting
(if (= i fail-value)
(signal "fail-value (~D) hit!" i)
i)))
(defun countdown-progress-indicator-style (&optional
(start-value 10)
(fail-value 1))
(handler-bind
((simple-condition (lambda (c)
(format t "fail (~A)~%" c)
fail-value))) ;; <--- I hoped the return value of the handler is returned by signal!
(countdown start-value fail-value)))
但是:即使处理了,signal
returns nil
.
(countdown-progress-indicator-style)
fail (fail-value (1) hit!)
(0 NIL 2 3 4 5 6 7 8 9)
因此,我的问题是,是否有我遗漏的功能或机制允许处理程序影响 signal
的 return 值。
我认为 CLHS 解释得很好:为了处理一个条件,您需要转移控制权。这可以是各种各样的事情,但是 通常 方法是调用重新启动。
(defun countdown (&optional
(start-value 10)
(fail-value 1))
(loop repeat start-value
for i from 0
collecting
(restart-case
(if (= i fail-value)
(signal "fail-value (~D) hit!" i)
i)
(use-fail-value (fv)
fv))))
(defun countdown-progress-indicator-style (&optional
(start-value 10)
(fail-value 1))
(handler-bind
((simple-condition (lambda (c)
(format t "Handling simple condition~%")
(apply #'format t
(simple-condition-format-control c)
(simple-condition-format-arguments c))
(invoke-restart 'use-fail-value
(first (simple-condition-format-arguments c))))))
(countdown start-value fail-value)))
这有点滥用simple-condition
的论点;您可能应该制定自己的条件,明确采用该值。
换句话说,你有了一个很好的发现。您可以发出异常情况信号,让 handler-bind
对其进行处理,然后继续执行(或者选择不使用重启)。
使用 handler-case
,您可以使用 return 值提前退出。
(handler-case (countdown 3)
(simple-condition ()
(print :exiting-now!)))
;;=>
:EXITING-NOW!
:EXITING-NOW!
If a condition is signaled for which there is an appropriate error-clause during the execution of expression and if there is no intervening handler for a condition of that type, then control is transferred to the body of the relevant error-clause.
从SBCL的文档中,我们可以了解到:
Invokes the signal facility on a condition formed from DATUM and ARGUMENTS. If the condition is not handled, NIL is returned.
它没有详细说明在处理条件的情况下 signal
return 是什么。
因此,我假设(猜测)处理程序可以以某种方式确定信号函数的 return 值:
(defun countdown (&optional
(start-value 10)
(fail-value 1))
(loop
repeat start-value
for i from 0
collecting
(if (= i fail-value)
(signal "fail-value (~D) hit!" i)
i)))
(defun countdown-progress-indicator-style (&optional
(start-value 10)
(fail-value 1))
(handler-bind
((simple-condition (lambda (c)
(format t "fail (~A)~%" c)
fail-value))) ;; <--- I hoped the return value of the handler is returned by signal!
(countdown start-value fail-value)))
但是:即使处理了,signal
returns nil
.
(countdown-progress-indicator-style)
fail (fail-value (1) hit!)
(0 NIL 2 3 4 5 6 7 8 9)
因此,我的问题是,是否有我遗漏的功能或机制允许处理程序影响 signal
的 return 值。
我认为 CLHS 解释得很好:为了处理一个条件,您需要转移控制权。这可以是各种各样的事情,但是 通常 方法是调用重新启动。
(defun countdown (&optional
(start-value 10)
(fail-value 1))
(loop repeat start-value
for i from 0
collecting
(restart-case
(if (= i fail-value)
(signal "fail-value (~D) hit!" i)
i)
(use-fail-value (fv)
fv))))
(defun countdown-progress-indicator-style (&optional
(start-value 10)
(fail-value 1))
(handler-bind
((simple-condition (lambda (c)
(format t "Handling simple condition~%")
(apply #'format t
(simple-condition-format-control c)
(simple-condition-format-arguments c))
(invoke-restart 'use-fail-value
(first (simple-condition-format-arguments c))))))
(countdown start-value fail-value)))
这有点滥用simple-condition
的论点;您可能应该制定自己的条件,明确采用该值。
换句话说,你有了一个很好的发现。您可以发出异常情况信号,让 handler-bind
对其进行处理,然后继续执行(或者选择不使用重启)。
使用 handler-case
,您可以使用 return 值提前退出。
(handler-case (countdown 3)
(simple-condition ()
(print :exiting-now!)))
;;=>
:EXITING-NOW!
:EXITING-NOW!
If a condition is signaled for which there is an appropriate error-clause during the execution of expression and if there is no intervening handler for a condition of that type, then control is transferred to the body of the relevant error-clause.