如何捕获编译时异常?
问题描述:
Clojure有可能捕获编译时发生的异常吗?使用的try/catch是好的,易于运行时异常,但假设我有:如何捕获编译时异常?
(defmacro will-throw-at-compile [] (assert false "it threw"))
(try (will-throw-at-compile) (catch Exception e "caught it"))
我找不到任何办法赶上这一点,捕捉从未发生过。我也尝试过不同类型的异常类,似乎不是问题所在。
我也想,既然上面的尝试是一个运行时调用,使得宏做在编译时尝试:
(defmacro t [x] (try x (catch Exception e "caught it")))
无法正常工作或:
(t (will-throw-at-compile))
也许不能完成?
答
如果宏处理它自己的异常,您可以使其工作。打出来的大多数宏的工作成一个函数:
(defn thrower []
(throw (Exception. "it threw")))
(defmacro will-throw
[]
(try
(thrower)
(catch Exception e (println "caught it")))
(println "leaving macro"))
(will-throw)
在运行这段代码的结果:
> lein run
caught it
leaving macro
的想法是把大部分或全部的宏功能集成到一个普通函数,因此它可以被称为&在编译时宏机制之外被测试。那么你可以使用像这样的常规单元测试:
(deftest t-thrower
(is (thrown? Exception (thrower)))
(println "t-thrower complete"))
> lein test
caught it
leaving macro
lein test tst.clj.core
t-thrower complete
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
我明白了。我试图找出一种方法来轻松地测试,当它们应该是由宏引发的断言时,所以我理想情况下不会改变宏本身,而是找到一种方法来检测它们是否发出异常。我想让宏实际上抛出断言,我只是想测试它。 – johnbakers
只需在您的测试中调用macroexpand,而不是评估宏调用。然后它在运行时发生,而这一切都不是问题。 – amalloy
@amalloy感谢的人。试过,工作正常。 – johnbakers