2016-05-13 49 views
3

我想包装系统或用户抛出的异常(无所谓)并强制它返回一些值。如何在Clojure宏中包装异常?

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

宏:

(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

回答

7

宏只返回代码要被评估的功能,所以你可以写safe-fn之类的这样的:

(defmacro safe-fn 
    [form] 
    `(try 
    ~form 
    (catch Throwable ~'_ 
     1))) 

例子:

(safe-fn (throw (RuntimeException. "Try me!"))) 
;=> 1 

见我的回答this question有关宏的更详细,具体使用它们捕获异常。

2

宏从the Tupelo librarywith-exception-default不正是你想要什么:

默认值在例外的情况

有时候,你知道的操作可能会导致异常,你 想有例外转换为默认值。这 是当你需要:

(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 

此功能善加利用在tupelo.parse,在那里你会发现 功能是这样工作的:

(parse-long "123")     ; throws if parse error 
;=> 123 
(parse-long "1xy23" :default 666) ; returns default val if parse error 
;=> 666