如何在 Clojure 宏中包装异常?
How to wrap Exception in Clojure Macro?
我想包装系统或用户抛出的异常(无关紧要)并将其强制为 return 某个值。
我为它写了宏,但它不起作用。
宏:
(defmacro safe-fn
[form]
(try
`(do ~form)
(catch Throwable e
1)))
用法:(safe-fn (throw (RuntimeException. "Try me!")))
实际输出:RuntimeException Try me! clojure-brave-and-true.core/eval2219 (form-init6122238559239237921.clj:1)
期望的输出:1
宏只是 return 待评估代码的函数,因此您可以这样写 safe-fn
:
(defmacro safe-fn
[form]
`(try
~form
(catch Throwable ~'_
1)))
示例:
(safe-fn (throw (RuntimeException. "Try me!")))
;=> 1
查看我对 的回答,了解有关宏的更多详细信息,特别是使用它们捕获异常的详细信息。
来自 the Tupelo library 的宏 with-exception-default
完全符合您的要求:
Default Value in Case of Exception
Sometimes you know an operation may result in an Exception, and you
would like to have the Exception converted into a default value. That
is when you need:
(with-exception-default default-val & body)
Evaluates body & returns its result. In the event of an exception the
specified default value is returned instead of the exception."
(with-exception-default 0
(Long/parseLong "12xy3"))
;=> 0
This feature is put to good use in tupelo.parse, where you will find
functions that work like this:
(parse-long "123") ; throws if parse error
;=> 123
(parse-long "1xy23" :default 666) ; returns default val if parse error
;=> 666
我想包装系统或用户抛出的异常(无关紧要)并将其强制为 return 某个值。
我为它写了宏,但它不起作用。
宏:
(defmacro safe-fn
[form]
(try
`(do ~form)
(catch Throwable e
1)))
用法:(safe-fn (throw (RuntimeException. "Try me!")))
实际输出:RuntimeException Try me! clojure-brave-and-true.core/eval2219 (form-init6122238559239237921.clj:1)
期望的输出:1
宏只是 return 待评估代码的函数,因此您可以这样写 safe-fn
:
(defmacro safe-fn
[form]
`(try
~form
(catch Throwable ~'_
1)))
示例:
(safe-fn (throw (RuntimeException. "Try me!")))
;=> 1
查看我对
来自 the Tupelo library 的宏 with-exception-default
完全符合您的要求:
Default Value in Case of Exception
Sometimes you know an operation may result in an Exception, and you would like to have the Exception converted into a default value. That is when you need:
(with-exception-default default-val & body)
Evaluates body & returns its result. In the event of an exception the
specified default value is returned instead of the exception."
(with-exception-default 0
(Long/parseLong "12xy3"))
;=> 0
This feature is put to good use in tupelo.parse, where you will find functions that work like this:
(parse-long "123") ; throws if parse error
;=> 123
(parse-long "1xy23" :default 666) ; returns default val if parse error
;=> 666