我将一些代码从2.9转换为2.10,并遇到了意外的编译错误。这是最小的形式:
在2.9.2中,这可以正常工作:
scala> List(1).flatMap(n => Set(1).collect { case w => w })
res0: List[Int] = List(1)
在2.10.0中,我们得到一个错误:
scala> List(1).flatMap(n => Set(1).collect { case w => w })
<console>:8: error: no type parameters for method flatMap: (f: Int => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[List[Int],B,That])That exist so that it can be applied to arguments (Int => scala.collection.immutable.Set[_ <: Int])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Int => scala.collection.immutable.Set[_ <: Int]
required: Int => scala.collection.GenTraversableOnce[?B]
List(1).flatMap(n => Set(1).collect { case w => w })
^
<console>:8: error: type mismatch;
found : Int => scala.collection.immutable.Set[_ <: Int]
required: Int => scala.collection.GenTraversableOnce[B]
List(1).flatMap(n => Set(1).collect { case w => w })
^
<console>:8: error: Cannot construct a collection of type That with elements of type B based on a collection of type List[Int].
List(1).flatMap(n => Set(1).collect { case w => w })
^
但是,如果我将内部结果显式转换为
List
或显式指定flatmap
的通用类型,则在2.10.0中可以正常工作:scala> List(1).flatMap(n => Set(1).collect { case w => w }.toList)
res1: List[Int] = List(1)
scala> List(1).flatMap[Int, List[Int]](n => Set(1).collect { case w => w })
res2: List[Int] = List(1)
有人可以告诉我对2.10所做的更改是什么,如果在2.9中未发生类型更改,则导致类型推断在此处失败?
编辑:
深入研究,我们可以看到问题是由于
collect
的行为不同引起的:在2.9.2中:
scala> Set(1).collect { case w => w }
res1: scala.collection.immutable.Set[Int] = Set(1)
在2.10.0中:
scala> Set(1).collect { case w => w }
res4: scala.collection.immutable.Set[_ <: Int] = Set(1)
大概原因与
Set
不同,例如List
是类型不变的。但是,更完整的解释,尤其是给出插入这种变化的动机的解释,将是很好的。 最佳答案
这是一个bug。您也可以通过键入模式来解决它,如
scala> Set(1).collect { case w => w }
res0: scala.collection.immutable.Set[_ <: Int] = Set(1)
scala> Set(1).collect { case w: Int => w }
res1: scala.collection.immutable.Set[Int] = Set(1)