请在2024 Clojure状态调查!中分享您的想法。

欢迎!请在关于页面查看有关如何使用本网站的更多信息。

0
编译器

以下最小示例展示了错误

(defn f ^double []) (f) => NullPointerException

在反编译函数f时,我发现了以下的返回表达式

return null.doubleValue();

这发生在Java互操作场景中,被调用的Java方法没有返回值,但在原始Clojure函数的返回位置。
编译器应该在编译时检查null

另一个例子 - 调用void返回类型的方法作为最后一个表达式失败的方式类似

(defn f ^double [^SomeClassToAvoidRuntimeReflection obj, x, y] (.someMethod obj, x, y)) (f obj, x, y) => NullPointerException

9 个答案

0

评论由:alexmiller

在此情况下,您期望发生什么?您将函数声明为返回double类型,但没有返回。

0

评论由:gv

由于这只是一个最小示例,错误相对容易发现。
考虑以下带有Java互操作的小示例

(defn f ^double [^SomeClassToAvoidRuntimeReflection obj, x, y] (.someMethod obj, x, y)) (f obj, x, y) => NullPointerException

在这个例子中,要找到NPE的原因要困难得多,因为您首先会怀疑objnull

我期望编译器在发出"return null.doubleValue();"的地方进行检查,然后显示错误消息,例如:"期望原始返回值类型 'double',但没有返回值。"

0

评论者:wagjo

在我看来,您的第二个示例看起来完全正常,编译器不应该报告任何错误,NPE检查必须运行时执行。

0

评论由:gv

@Jozef:不,你错了。编译器通过反射在编译时推断调用方法不返回值,并发出 "return null.doubleValue()"。因此,这可以并且应该报告为编译时的显式错误。我添加了一个类型提示,以明确没有任何运行时反射涉及。
如果您发出类似于 "return somevar.doubleValue()" 的内容,那么您就会是对的,因为在编译时不知道可能的 "null" 值。

0

评论者:jafingerhut

在您的示例中,方法 'someMethod' 是声明为返回 void 还是其他类型?将此信息添加到示例中可能有助于澄清。

0

评论者:wagjo

Gunnar,第二个示例含糊不清,偏离了讨论。无论如何,无论是通过原生方法返回错误类型还是不是,首先它是一次用户错误。目前它在运行时报告。对我来说,这个工单应该是一次小型的增强而不是缺陷。

0

评论由:gv

是的,这是一个用户错误。但这是一个比必要的更难调试的错误。
此外,这是一个明显的缺陷,因为发出 'null.doubleValue()' 不能被视为有效的编译。

Andy,是的 'someMethod' 是声明为返回 void。我打算编辑原始工单文本以添加示例和 Java 方法返回值信息,但看起来 Jira 不允许我这样做。

0

评论由:alexmiller

我在描述中添加了第二个示例(带有解释的注释)。

0
参考:https://clojure.atlassian.net/browse/CLJ-1432(由 ale x+import 报告)
...