Common Lisp异常后如何继续正常执行?

How to continue normal execution after exception in Common Lisp?

我想捕获 unbound-variable 异常并避免它们,即时创建一些变量而不会中断执行。 我正在尝试在以下代码中将 handler-bindinvoke-restart 一起使用:

(defmacro my-progn (&rest rest)
  `(handler-bind
    ((unbound-variable
      (lambda (x)
        (progn
          ;(format t "UNBOUND VAR: ~a~%"
          ;  (symbol-name (cell-error-name x)))
          (invoke-restart 'just-continue)))))
    (progn ,@(mapcar (lambda (x)
                      `(restart-case ,x (just-continue () "XXXX"))) rest))))

(my-progn
  (print "AAA")
  (print xxxx) ;; xxxx is unbound
  (print "BBB"))

结果是:

"AAA"
"BBB" 

但我想继续执行第二个 print,只是将未绑定变量 xxxx 替换为字符串 "XXXX":

"AAA"
"XXXX"
"BBB" 

当然,我可以用handler-bind将语法树中的任何符号包裹起来,但恐怕这会产生巨大的开销。

有没有办法只捕获 unbound-variable 异常并使用动态生成的值而不是丢失变量继续执行代码?

您可以使用合适的 standard restart use-value.

(handler-bind
    ((unbound-variable
      (lambda (c)
        (declare (ignore c))
        (use-value "XXXX"))))
  (print "AAA")
  (print xxxx)
  (print "BBB"))