请在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

安尼娅,您的第二个例子含混不清且偏离了讨论。无论如何,无论是通过本地方法还是通过其他方式返回错误类型,首先都是用户错误。目前这是在运行时报告的。对我来说,这个条目应该是一个小增强功能而不是缺陷。

0

评论由:gv撰写

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

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

0

评论由:alexmiller撰写

我在描述中添加了第二个示例(带有说明性空注释)。

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