请在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的原因要困难得多,因为您首先会怀疑obj可能是null

我期望在编译器发出“return null.doubleValue();”点进行检查,然后显示错误消息,例如“预期原始返回类型为'double',但未返回任何值。”。

0

评论者:wagjo

您提供的第二个示例在我看来完全没问题,编译器不应该报错,空指针检查必须在运行时进行。

0

评论由:gv

@Jozef:不,你是错的。编译器通过反射在编译时推断出被调用的方法不返回值,并发出“return null.doubleValue()”。因此,这可以也应该在编译时视为显式错误。我添加了类型提示,以便清楚地表明没有运行时反射。
如果你看到的编译器发出的像是“return somevar.doubleValue();”,那么在编译时就没有关于可能的“null”值的了解。

0

评论者:jafingerhut

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

0

评论者:wagjo

jira,第二个示例有歧义,偏离了讨论的话题。无论如何,不论是返回错误类型是通过本地方法还是不是,首先都是用户的错误。目前,这是在运行时报告的。对我来说,这个票据应该是一个小增强,而不是缺陷。

0

评论由:gv

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

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

0

评论由:alexmiller

我在描述中添加了第二个例子(带解释性空值注释)。

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