0

一个简单的问题。::immutable 类的方法List定义为:

密封抽象类 List[+A] ...

def ::[B >: A](x: B): 列表[B]

假设我有:

class Fruit
class Mango extends Fruit
scala> val d:List[Fruit] = List.empty[Fruit]
d: List[Fruit] = List()

scala> new Mango :: d
res5: List[Fruit] = List(Mango@272d6774)

现在我在这里很困惑。根据::声明,参数类型应该是逆变的。即在这种情况下,任何类>: Fruit(我理解为什么会这样)。但我不明白的是,Mango <: Fruit为什么编译器不抛出错误?

4

2 回答 2

5

即使是不变的,您仍然可以添加Mangoto ,仅仅因为仍然是. 用一个普通的旧 java 列表来考虑它:dListMangoFruit

val d = new java.util.ArrayList[Fruit]
d.add(new Mango)

所以逆变不会限制您添加子类型的能力 - 它使您能够添加超类型并从中获取编译器检查的列表类型:

val d: List[Fruit] = Nil
val a: List[Plant] = new Carrot :: d
于 2013-02-15T12:13:10.540 回答
3

在行

new Mango :: d

您希望编译器推理:“new Mango有类型Mango并且d有类型List[Fruit],所以List[Fruit].::(Mango)需要进行类型检查,但它没有”。在这种情况下,这确实是一个错误。

但实际上,它的原因不同:“我需要new Mango :: d进行类型检查,所以new Mango必须有某种类型B,这样B :> Fruit。有这样的B吗?是的,B = Fruit。” 所以没有错误。

于 2013-02-15T13:02:08.243 回答