【发布时间】:2016-10-16 23:53:50
【问题描述】:
我正在学习Functional Programming Principles in Scala,在完成Subtyping and Generics 的讲座时,我对协方差感到困惑:
给定:NonEmpty <: IntSet 或 NonEmpty 是 IntSet 的子类型
是 List[NonEmpty] <: List[IntSet] 还是 List[NonEmpty] 的子类型
List[IntSet]?
答案是有道理的,因为非空集合列表是任意集合列表的特例。
这个答案是否暗示List[NonEmpty] 是List[IntSet] 的子类型?
所以我尝试了这个:
val nonEmpty: List[NonEmpty] = null
val intSet: List[IntSet] = nonEmpty
然后我得到一个编译错误:
List[NonEmpty] 类型的表达式不符合预期类型 列表[IntSet]
据我所知,泛型在 Java 中是不变的,而泛型在 Scala 中是协变的 或者我对协方差有错误的理解?
编辑:
这里是IntSet, NonEmpty, List的定义:
abstract class IntSet {
def contains(x: Int): Boolean
def incl(x: Int): IntSet
def union(other: IntSet): IntSet
}
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {...}
trait List[T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
}
【问题讨论】:
-
这应该可以编译(假设您使用的是标准 Scala
List)。NonEmpty和IntSet的定义是什么? -
@AlexeyRomanov:我更改为 Scala List 并且它符合要求,但我不明白为什么,它们不是都是泛型类型吗?
-
scala.collection.immutable.List[+A]在A上是协变的,由+符号表示。
标签: java scala generics functional-programming covariance