在Ceylon中返回max {}的类型

时间:2013-12-04 00:55:42

标签: generics type-inference ceylon

我明白为什么max({})的推断返回类型是Null(我觉得这个函数如何与空/可能空/非空迭代一起工作很棒),但为什么使用空命名参数列表 - max{} - 推断为返回Nothing?为什么这些案件有所不同?那是为了吗?

这个编译并运行得很好,

Nothing foo = max{};

虽然如果实际评估nothing我会预期它会立即失败。由于Nothing是所有内容的子类型,您甚至可以这样做,

Integer bar = max{};

并且编译器不会抱怨,但是运行它会产生java.lang.NullPointerException。什么?!我以为我们永远不应该在锡兰看到它!

1 个答案:

答案 0 :(得分:4)

哇,好的!我花了几分钟时间想着解这里发生了什么。所以,正如我猜你知道的那样:

max {}

理论上应该与这些相同:

max({})
max { values={}; }

现在,如果您编写其中任何一种排列,您将获得Null推断出的正确返回类型max()。而且,实际上,如果您执行任一示例,结果都是正确的null

的确,即使我运行以下程序:

void run() => print( max{} );

按照我们的预期打印<null>

所以这里发生的是我的类型参数推理算法中有一个错误,它在推断类型args时没有考虑“隐式”空可迭代参数{Nothing*}。因此,您为Nothing的两个类型参数获取推断类型max(),因为类型参数被视为不受约束。然后,由于NothingInteger的子类型,因此typechecker允许您将结果分配给Integer。当然,函数实际返回的空值不能赋予Integer,因此你得到的NPE当然不会发生。

解决方案是我需要修复bug。它将是一个很小的衬垫。

如果你不介意的话,请你提交一份关于锡兰规范的错误报告,明天我会修复它。

谢谢!