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

问题描述 投票:1回答:1

我想抓住 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 异常,并用动态生成的值代替缺失的变量继续执行代码?

common-lisp sbcl
1个回答
6
投票

你可以使用适当的 标准重启 use-value.

(handler-bind
    ((unbound-variable
      (lambda (c)
        (declare (ignore c))
        (use-value "XXXX"))))
  (print "AAA")
  (print xxxx)
  (print "BBB"))
© www.soinside.com 2019 - 2024. All rights reserved.