gpt4 book ai didi

clojure - 如何在 Clojure 中捕获一个 arity 异常?

转载 作者:行者123 更新时间:2023-12-02 08:04:27 28 4
gpt4 key购买 nike

我正在尝试像这样捕获一个异常:

(try
(inc)
(catch clojure.lang.ArityException e
(str "caught exception: " (.getMessage e))))))

在这种情况下,我在调用 inc 时没有向它传递一个数字,它正确地抛出了一个异常。但是,当我运行它时并没有捕获到该异常:

(try
(inc)
(catch clojure.lang.ArityException e
(str "caught exception: " (.getMessage e))))))

; => CompilerException clojure.lang.ArityException: Wrong number of args (0) passed to: core/inc--inliner--4489

通常 try catch 任何 Exception 而不是 clojure.lang.ArityException 仍然会抛出它。

我相信任何在 Clojure 开发方面经验丰富的人都会立即发现我的错误。

最佳答案

在某些情况下,您可以捕获 ArityException;取决于导致 ArityException 的上下文和函数。


我马上承认我在某些方面进行了推测,因为我之前从未深入探讨过这个问题。

首先,看看如果在提供的参数数量明显错误的上下文中调用 inc 会发生什么:

(inc)
CompilerException clojure.lang.ArityException: Wrong number of args (0) passed to: core/inc--inliner--4489, compiling: . . .

有趣的部分是inc--inliner--4489。如果您查看 inc 的定义,它会附加以下元数据:

:inline (fn [x] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_inc 'inc) ~x)))

我以前从未深入研究过 :inline,但我一直假设这意味着它将尝试内联调用以(略微)减少开销。在这种情况下,它试图将 inc 内联为对 clojure.lang.Numbers/incclojure.lang.Numbers/unchecked_inc< 的调用;取决于 *unchecked-math* 的状态。还要注意错误是如何开始的:

CompilerException clojure.lang.ArityException

在您的示例中,您无法直接捕获 (inc),因为该调用在代码运行之前的编译时间 失败。它知道 (inc) 永远不会正确,所以它立即失败。不过,这是一件好事。 (inc) 永远不会是正确的,所以无论如何都没有必要试图捕获它。


然而,在某些情况下,捕获 arity 异常可能是有意义的(尽管可能有更好的方法来解决问题*)。假设您不允许对 inc 的调用被内联,正如@Rulle 建议的那样,应用 参数:

(try
(apply inc [])

(catch clojure.lang.ArityException e
(println "Caught!")))

Caught!

编译器无法确定 inc 是否会失败,因为它取决于提供给 apply 的参数数量;这可能取决于运行时的事情。在这种情况下,代码实际上能够运行,也能够捕获其 ArityException


:inline 排除在等式之外,您还可以看到您的自定义函数可以更轻松地捕获其 ArityException,因为调用不是内联,所以它不会在编译时失败:

(defn hello [arg]) 

(try
(hello) ; No apply

(catch clojure.lang.ArityException e
(println "Caught!")))

Caught!

* 我不能说我曾经必须捕获 ArityException,而且我想不出在任何情况下这样做是合适的。即使您正在使用 apply,提前验证参数甚至重新考虑您对 apply 的使用也会更有意义。如果使用 apply 导致 ArityException,您的逻辑中可能存在缺陷,使用 try 只是贴上创可贴.

关于clojure - 如何在 Clojure 中捕获一个 arity 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53127762/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com