【问题标题】:The type requirement [B >: A] for ++ operator in Scala ListsScala 列表中 ++ 运算符的类型要求 [B >: A]
【发布时间】:2018-08-12 01:11:05
【问题描述】:

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

最常见的解释是“接受任何作为 A 的超类的 B”

但是我可以执行以下代码并使用class B(Sprite)调用++,它不是class A(可乐)的超类。

我知道 scala 在这种情况下可能会推断出最近的共同祖先,并在调用++ 时创建SoftDrink 对象列表,如下所示。

我的问题是,API 文档中的哪个位置声明可以将与 A 具有共同祖先的 B 传递给 ++ 运算符? [B >: A] 在合同要求中似乎很简单,即 BA 的超类,而不是关于共同祖先的任何东西。

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())

【问题讨论】:

    标签: scala covariance scala-collections contravariance


    【解决方案1】:

    API 文档中的什么地方声明可以将具有与 A 共同祖先的 B 传递给 ++ 运算符?

    不需要,因为这超出了类型下界的定义。 SpriteCola最接近的超类型是SoftDrink,从而满足编译器的要求。

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

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

    【讨论】:

      【解决方案2】:

      Scala 文档,列表 ++

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 2017-12-28
        • 2016-01-21
        • 1970-01-01
        • 2011-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多