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 发表的评论

在这种情况下,您期望发生什么?您声明了一个返回双精度型的函数但没有返回值。

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 发表的评论

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

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