Scala列表中++运算符的类型要求[B>:A]

时间:2018-03-04 06:07:24

标签: scala covariance scala-collections contravariance

我有一个关于Scala列表中++运算符的基本问题,以及类型符号[B>:A]。

最常见的解释为"接受任何B超级A"

然后我可以执行类似下面代码的操作并使用++(Sprite)调用class B,而class A(Sprite)不是SoftDrink(Cola)的超类。

我理解,然后scala可能会在这种情况下推断最接近的共同祖先,并在调用++时创建B对象列表,如下所示。

我的问题是,它在API文档中的哪个位置表明可以将A传递给++ [B >: A]运算符的公共祖先? B合同要求A似乎非常直截了当abstract class Drink abstract class SoftDrink() extends Drink abstract class Juice() extends Drink case class Cola() extends SoftDrink case class Sprite() extends SoftDrink scala> val al = List(Cola(), Cola()) al: List[Cola] = List(Cola(), Cola()) scala> val bl = List(Sprite()) bl: List[Sprite] = List(Sprite()) scala> val cl = al ++ bl cl: List[SoftDrink with Product with Serializable] = List(Cola(), Cola(), Sprite()) 是{{1}}的超类而不是共同祖先。

{{1}}

2 个答案:

答案 0 :(得分:3)

  

在API文档中,它是否表示可以传递一个具有A to ++运算符的共同祖先的B?

它不需要,因为它不属于较低类型边界的定义。最接近的超级类型SpriteColaSoftDrink,因此满足了编译器的要求。

你说得对,编译器帮助搜索这两种类型的共同祖先可能不是直观的,但它仍然属于定义的标准。

Scala规范的相关部分指出了这一点Conformance

答案 1 :(得分:1)

Scala docs,List ++

  

def ++[B](that: GenTraversableOnce[B]): List[B]

     

返回一个新列表,其中包含左侧操作数后跟的元素   右手操作数的元素。列表的元素类型   是包含元素类型的最具体的超类   两个操作数。