这有点类似于this question,但是我想捕获多个异常并全部处理。在Ruby中,我可以写
begin
rand(2) == 0 ? ([] + '') : (foo)
rescue TypeError, NameError => e
puts "oops: #{e.message}"
end
我可以在Clojure中做同样的事情吗?现在,我let
一个函数,只在每个catch
主体中调用它。
答案 0 :(得分:7)
(ns mastering.stackoverflow
(:use
[slingshot.slingshot :only [try+]]))
(try+
; ...
(catch (comp #{TypeError NameError} class) _ "caught"))
The slingshot library在github上可用。
答案 1 :(得分:2)
您还可以委托给局部函数,尽管它有点冗长:
(let [handle #(println %)]
(try
(throwing-op)
(catch TypeError e (handle e))
(catch NameError e (handle e))))
答案 2 :(得分:1)
目前还没有简单的内置解决方案,但是有open ticket。
您可以在catch块中手动键入分派类型。
(try
(do-dangerous-operation-here)
(catch Exception e
(condp (fn [cs t] (some #(instance? % t) cs)) e
[IllegalStateException IllegalArgumentException]
(println "Either illegal state or illegal argument!")
[java.sql.SQLException]
(println "Sql error!")
;; whe pass through the exception when not handled
(throw e))))
答案 3 :(得分:0)
您也可以使用此宏:
(defmacro try*
"Macro to catch multiple exceptions with one catch body.
Usage:
(try*
(println :a)
(println :b)
(catch* [A B] e (println (class e)))
(catch C e (println :C))
(finally (println :finally-clause)))
Will be expanded to:
(try
(println :a)
(println :b)
(catch A e (println (class e)))
(catch B e (println (class e)))
(catch C e (println :C))
(finally (println :finally-clause)))
"
[& body]
(letfn [(catch*? [form]
(and (seq form)
(= (first form) 'catch*)))
(expand [[_catch* classes & catch-tail]]
(map #(list* 'catch % catch-tail) classes))
(transform [form]
(if (catch*? form)
(expand form)
[form]))]
(cons 'try (mapcat transform body))))