Exception 公共lisp异常处理(条件和重新启动)
我已经阅读了common lisp“实用common lisp”异常处理章节好几天了,但我现在对示例和解释感到非常困惑,同时我尝试编写一些测试示例,但它没有像我预期的那样工作,下面是我的测试示例Exception 公共lisp异常处理(条件和重新启动),exception,common-lisp,conditional-statements,restart,condition-system,Exception,Common Lisp,Conditional Statements,Restart,Condition System,我已经阅读了common lisp“实用common lisp”异常处理章节好几天了,但我现在对示例和解释感到非常困惑,同时我尝试编写一些测试示例,但它没有像我预期的那样工作,下面是我的测试示例 条件定义 (define-condition evenp-error (error) ((text :initarg :text :reader text))) 定义打印奇数的函数 (defun filter-evenp (lst) (dolist (x lst) (if (not
(define-condition evenp-error (error)
((text :initarg :text :reader text)))
(defun filter-evenp (lst)
(dolist (x lst)
(if (not (evenp x))
(print x)
(error 'evenp-error :text x))))
(defun skip-evenp (c) (invoke-start 'skip-evenp))
(restart-case (filter-evenp (list 1 2 3 4 5))
(skip-evenp () nil))
我想做的就是打印所有奇数,跳过偶数错误,我的样本有什么问题?有人帮忙吗?非常感谢 您需要将您的
RESTART-CASE
放在要在以下位置重新启动执行的位置:
(defun filter-evenp (lst)
(dolist (x lst)
(restart-case
(if (not (evenp x))
(print x)
(error 'evenp-error :text x))
(skip-evenp () nil))))
然后您应该使用HANDLER-BIND
来处理错误:
(handler-bind ((evenp-error #'skip-evenp))
(filter-evenp (list 1 2 3 4 5)))
非常详细,但条件系统可能需要一些时间才能适应。你可能会对肯特·皮特曼的文章感兴趣:和
这些在中引用。还有许多其他的参考文献,比如这个或C2维基的条目
定义重新启动
A基本上说:
我将执行此表单,我不在乎它是否表示条件。但如果确实如此,并且您希望从这种情况中恢复过来,我可以用以下几种不同的方法来解决这个问题(重试、忽略等)
通常无法说明如何从调用点调用的代码中的错误中恢复。换句话说,filter evenp
应该用restart case
包装代码,以提供替代路径。对于您的示例,使用就足够了,它在建立继续
重新启动时发出错误信号
(if (evenp x)
(cerror "Ignore even number" 'evenp-error :text x)
(print x))
作为练习,您可以尝试将(cerror…
替换为显式重新启动案例
构造
然后,如果您测试代码,您应该会看到调试器弹出并显示继续
重新启动。如果定义了自己的重新启动,则可以使用不同的名称
调用重启
在您的skip evenp
函数中,您调用了一个此时未建立的重启,我认为您与skip evenp
命名重启和函数混淆了
您应该做的是通过调用重启来处理错误
在这里,您希望发出错误信号的代码继续,因此您确实不希望解除执行堆栈。这就是为什么你必须使用
当然,您可以像以前一样将匿名lambda提取到自定义函数中。您提供的解决方案正是我想要的,但我仍然对重新启动的内容感到困惑,让我尝试找到更多的资料来解决它,谢谢@用户2015063如果用户是有用的,考虑用绿色复选标记接受它。如果这对你有帮助的话,我会添加更多的参考资料。谢谢你的回复,我仍然不确定“skip-evenp”指的是哪里。to?
#“SKIP-EVENP
指的是该名称的函数(这就是#“
的意思)。HANDLER-BIND
告诉它通过调用函数SKIP-EVENP
@user2015063#来处理任何EVENP-ERROR
,
是一个读卡器宏:上述函数相当于(函数跳过事件)
并使用特殊运算符引用按词汇绑定到跳过事件符号的函数对象。@jkiiski非常感谢,我通过google搜索了更多示例后终于找到了它,
(handler-bind ((evenp-error (lambda (e) (invoke-restart 'continue))))
(filter-evenp '(1 2 3 4)))
1
3