如何在Clojure宏中包装异常?

如何在Clojure宏中包装异常?,clojure,functional-programming,macros,lisp,Clojure,Functional Programming,Macros,Lisp,我想包装系统或用户抛出的异常(无所谓),并强制它返回一些值 我为它编写了宏,但它不起作用 宏: (defmacro safe-fn [form] (try `(do ~form) (catch Throwable e 1))) 用法:(安全fn(throw(RuntimeException.“Try me!”)) 实际输出:RuntimeException请尝试!clojure-brave-and-true.core/eval2219(form-init61

我想包装系统或用户抛出的异常(无所谓),并强制它返回一些值

我为它编写了宏,但它不起作用

宏:

(defmacro safe-fn
  [form]
  (try
    `(do ~form)
    (catch Throwable e
      1)))
用法:
(安全fn(throw(RuntimeException.“Try me!”))

实际输出:
RuntimeException请尝试!clojure-brave-and-true.core/eval2219(form-init6122238559239237921.clj:1)


所需的输出:
1

宏只是返回要计算的代码的函数,因此您可以这样编写
safe fn

(defmacro-safe fn
[表格]
`(试试看
~form
(可丢弃的捕获物~'_
1)))
例如:

(安全fn(抛出(RuntimeException.“试试我!”)
;=> 1.

有关宏的更多详细信息,特别是关于使用宏捕获异常的详细信息,请参见我的答案。

中带有异常默认值的宏
的功能正是您想要的:

异常情况下的默认值

有时,您知道某个操作可能会导致异常,并且 希望将异常转换为默认值。那个 是指您需要:

这个特性在tupelo.parse中得到了很好的使用,您可以在这里找到 工作方式如下的函数:

(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
(parse-long "123")                  ; throws if parse error
;=> 123
(parse-long "1xy23" :default 666)   ; returns default val if parse error
;=> 666