7

扩大联合类型已在此处讨论,但我似乎无法找到以下案例的答案

让我们从以下内容开始

val x = List(1, 2, "a")

这个异构列表的推断List[Any]就像在 Scala 2 中一样

然而以下

val x2 = List(List(1, 2), Vector("a", "b"))

被推断为List[scala.collection.immutable.AbstractSeq[Int | String]]

这是相当令人困惑的行为。为什么在一种情况下推断出两种不相交类型的 LUB,Any而在另一种情况下推断出联合类型?

如果这只是一个设计决策,是否有任何应该注意的情况?

4

1 回答 1

8

更聪明的国家

我们避免推断联合类型的原因与我们避免推断单例类型的原因相同,因为有时它们“太精确”

List(1,2)我对这句话的解释是,键入asList[Int]而不是List[1 | 2]List(new Cat, new Dog)asList[Animal]而不是更有意义List[Cat | Dog]

另请参阅(我的)相关问题中 Dmytro 的评论

引自guillaume.martres.me/talks/dotty-tutorial /#/1/13 (幻灯片 15“类型推断和联合类型”):“默认情况下,Dotty 不推断联合类型,它们由非联合近似超类型。联合类型可能“过于精确”并阻止合法代码编译“

另请参阅23:38的谈话“Dotty and types: the story so far”。

然而,根据smarter只执行一次联合扩展以避免无限 LUB :

当我们进行一次加宽时,结果类型可能在某处有一个联合(如文档中联合类型的连接部分中的示例),我们不会加宽,如果我们确实递归地进行加宽,我们可以得到一个确实是无限润滑

于 2020-09-16T20:35:49.120 回答