问题描述
已经讨论了here的简化联合类型,但我似乎无法找到以下情况的答案
让我们从以下内容开始
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
,而在另一种情况下被推断为联合类型?
如果仅是设计决策,是否有任何此类情况需要人们注意?
解决方法
smarter状态
我们避免推断联合类型,原因与避免推断相同 单例类型,因为有时它们“太精确”了
我对此声明的解释是,将List(1,2)
键入为List[Int]
而不是List[1 | 2]
,或者将List(new Cat,new Dog)
键入为List[Animal]
而不是{ {1}}。
另请参阅我的相关question中Dmytro的评论
guillaume.martres.me/talks/dotty-tutorial/#/1/13的语录(幻灯片15 “类型推断和并集类型”):“默认情况下,Dotty不会推断 联合类型,它们由非联合超类型近似。联盟 类型可能“过于精确”并阻止了合法代码的编译”
另请参阅23:38上有关话题和类型的讨论:
但是,仅根据一次扩大联合,以避免无限LUB:
当我们进行一次扩展时,结果类型可能具有并集 某处(例如,第smarter节中的示例 文档),我们不会扩大,如果我们以递归方式进行扩大, 我们确实可以得到无限润滑