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))))