请分享您的想法,参与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

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

0

评论者:wagjo

Gunnar,第二个例子不明确,偏离了讨论。无论如何,无论返回错误的类型是通过本地方法还是其他方式,它首先是一个用户错误。目前它在运行时报告。对我来说,这个工单应该是一个小的增强,而不是缺陷。

0

评论由:gv

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

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

0

评论由:alexmiller

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

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