我正在使用弹弓的throw+
宏来引发一个类似的异常:
(throw+ {:type ::urlparse})
类型检查器不喜欢它:
Type Error (stream2es/http.clj:79:17) Bad arguments to apply:
Target: [String t/Any * -> String]
Arguments: (PersistentList String)
in: (clojure.core/apply clojure.core/format (clojure.core/list "throw+: %s" (clojure.core/pr-str %)))
Type Checker: Found 1 error
macro in slingshot看起来像:
(defmacro throw+
([object]
`(throw+ ~object "throw+: %s" (pr-str ~'%)))
([object message]
`(throw+ ~object "%s" ~message))
([object fmt arg & args]
`(let [environment# (s/environment)
~'% ~object
message# (apply format (list ~fmt ~arg ~@args))
stack-trace# (s/stack-trace)]
(s/throw-context ~'% message# stack-trace# environment#)))
([]
`(s/rethrow)))
我在ann ^:no-check
和apply
上尝试过各种format
表单但没有效果。因为它是一个宏,我假设我不能注释它,因为它取代了那里的代码。但我也不能像this other answer中建议的那样重写宏中的代码,因为它在库中。我如何逐步输入这种情况?
答案 0 :(得分:1)
如果您无法重写throw+
的实现,我建议使用这样的包装宏。
(defmacro typed-throw+ [object]
`(let [o# ~object]
(t/tc-ignore
(throw+ o#))
(throw (Exception.)))) ; unreachable
;; other arities are an exercise ..
这样,你仍然键入检查参数,core.typed仍然认为throw+
总是抛出异常 - 它并不是真的知道这一点,但是最终的throw子句允许core.typed给出整个表达式类型Nothing
。
真正的答案应该是我们可以改进apply
以了解应用非空列表将至少满足一个参数,但是这个答案今天应该有用。