【问题标题】:How to wrap Exception in Clojure Macro?如何在 Clojure 宏中包装异常?
【发布时间】:2016-09-09 20:17:48
【问题描述】:

我想包装系统或用户抛出的异常(没关系)并强制它返回一些值。

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

宏:

(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

【问题讨论】:

    标签: clojure functional-programming macros lisp


    【解决方案1】:

    the Tupelo library 中的宏 with-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
    

    【讨论】:

      【解决方案2】:

      宏只是返回要评估的代码的函数,所以你可以这样写safe-fn

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

      例子:

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

      请参阅我对this question 的答复,了解有关宏的更多详细信息,特别是有关使用它们捕获异常的信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-24
        • 1970-01-01
        • 2015-10-27
        • 2013-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多