我明白为什么max({})
的推断返回类型是Null
(我觉得这个函数如何与空/可能空/非空迭代一起工作很棒),但为什么使用空命名参数列表 - max{}
- 推断为返回Nothing
?为什么这些案件有所不同?那是为了吗?
这个编译并运行得很好,
Nothing foo = max{};
虽然如果实际评估nothing
我会预期它会立即失败。由于Nothing
是所有内容的子类型,您甚至可以这样做,
Integer bar = max{};
并且编译器不会抱怨,但是运行它会产生java.lang.NullPointerException
。什么?!我以为我们永远不应该在锡兰看到它!
答案 0 :(得分:4)
max {}
理论上应该与这些相同:
max({})
max { values={}; }
现在,如果您编写其中任何一种排列,您将获得Null
推断出的正确返回类型max()
。而且,实际上,如果您执行任一示例,结果都是正确的null
。
的确,即使我运行以下程序:
void run() => print( max{} );
按照我们的预期打印<null>
。
所以这里发生的是我的类型参数推理算法中有一个错误,它在推断类型args时没有考虑“隐式”空可迭代参数{Nothing*}
。因此,您为Nothing
的两个类型参数获取推断类型max()
,因为类型参数被视为不受约束。然后,由于Nothing
是Integer
的子类型,因此typechecker允许您将结果分配给Integer
。当然,函数实际返回的空值不能赋予Integer
,因此你得到的NPE当然不会发生。
解决方案是我需要修复bug。它将是一个很小的衬垫。
如果你不介意的话,请你提交一份关于锡兰规范的错误报告,明天我会修复它。
谢谢!