Common lisp 非宏的HANDLER-CASE备选方案 考虑下面的代码: (define-condition some-condition (error) nil) (defmethod print-object ((obj some-condition) stream) (format stream "HELLO THERE")) (defmacro error-report-test-aux (fn-to-cause-error error-type-to-catch fn-to-handle-error expected-message) `(let ((result-message (handler-case (funcall ,fn-to-cause-error) (,error-type-to-catch (e) (funcall ,fn-to-handle-error e))))) (assert (string= result-message ,expected-message)) t))
我可以这样使用它:Common lisp 非宏的HANDLER-CASE备选方案 考虑下面的代码: (define-condition some-condition (error) nil) (defmethod print-object ((obj some-condition) stream) (format stream "HELLO THERE")) (defmacro error-report-test-aux (fn-to-cause-error error-type-to-catch fn-to-handle-error expected-message) `(let ((result-message (handler-case (funcall ,fn-to-cause-error) (,error-type-to-catch (e) (funcall ,fn-to-handle-error e))))) (assert (string= result-message ,expected-message)) t)),common-lisp,Common Lisp,我可以这样使用它: (error-report-test-aux (lambda () (error 'some-condition)) some-condition #'princ-to-string "HELLO THERE") 但是我想让错误报告test aux成为一个函数而不是宏,这样我就可以在变量中向它传递一种条件 简单地编写defun而不是
(error-report-test-aux (lambda () (error 'some-condition))
some-condition
#'princ-to-string
"HELLO THERE")
但是我想让错误报告test aux
成为一个函数而不是宏,这样我就可以在变量中向它传递一种条件
简单地编写defun
而不是defmacro
并删除反引号和逗号是不起作用的,因为处理程序大小写
是宏,它不会计算错误类型以捕获
我的问题是:是否有类似于处理程序case
的东西可以计算它的参数(特别是条件类型参数)?是和否:-)
对你的问题没有回答
没有标准函数可以做您想要做的事情,因为捕捉错误需要建立绑定,而通常需要绑定常量符号(如中),因为这样更容易优化
您可以考虑创建一个“通用”处理程序,然后拒绝处理“乏味”的条件(如评论中的JJKISISKI建议),但我不确定是否符合您的确切要求(未经测试):
是的,具体实施 如果您的实现通过绑定一个内部全局变量来实现,您可以自己绑定它,从而将您的错误报告测试aux
作为一个函数来实现
这可能不是最好的主意(您的代码与特定的实现结合在一起)
是的,有点
您可以使用
some condition
命名CLOS类并使用泛型函数而不是宏的事实。我不认为将nil
作为stream
传递到print object
是兼容的代码。您可能打算使用princ来字符串
,而不是那里的lambda
。您可以尝试使用HANDLER-BIND
为任何条件
建立一个处理程序,然后检查条件的类型是否正确,如果不正确则拒绝处理。@sds您的评论让我读了一大堆CLH。现在我知道更多了,谢谢。
(defun error-report-test-aux (fn-to-cause-error error-type-to-catch expected-message)
(catch 'trap
(handler-bind ((error
(lambda (condition)
(when (typep condition error-type-to-catch)
(throw 'trap (string= (princ-to-string condition)
expected-message))))))
(funcall fn-to-cause-error))))