Scala F-有界类型多态性

时间:2016-05-25 09:03:19

标签: scala scala-collections

trait Account[T <: Account[T]]

case class BrokerAccount(total:BigDecimal) extends Account[BrokerAccount]
case class SavingsAccount(total:BigDecimal) extends Account[SavingsAccount]

下面的函数声明和调用工作正常。

def foo1( xs: Array[T forSome { type T <: Account[T] }]):Array[T forSome { type T <: Account[T] }] = xs
foo1(Array(BrokerAccount(100),SavingsAccount(50)))

但是下面的调用会产生编译错误。

def foo2( xs: List[T forSome { type T <: Account[T] }]):List[T forSome { type T <: Account[T] }] = xs
foo2(List(BrokerAccount(100),SavingsAccount(50)))

错误

  

Main.scala:14:错误:类型不匹配;
  找到:列出[具有Seri​​alizable with Main.Account的产品[_&gt ;: Main.SavingsAccount与Main.BrokerAccount&lt ;: Product with Serializable with Main.Account [_&gt ;: Main.SavingsAccount with Main.BrokerAccount&lt ;: Product with Serializable接口]]]
  required:List [T forSome {type T&lt;:Main.Account [T]}] foo2(List(BrokerAccount(100),SavingsAccount(50)))

有人可以解释一下为什么在以后的情况下会发生编译错误吗?

1 个答案:

答案 0 :(得分:3)

问题的关键是方差 - 你试图在协变位置(函数返回类型)返回逆变值。 尽管List类型在其参数(trait List[+A])中是协变的,但这实质上意味着它的值是逆变的(可以分配给超类型列表):

val listOfSupers: List[_ >: Account[_]] = List(BrokerAccount(100), SavingsAccount(50))

您尝试从函数foo2返回的内容完全相反 - List[_ <: Account[_]],因此编译错误。

如果您使用List代替Set而不是Array,那么它的类型参数就像int length = Math.min(arrayA.length, arrayB.length); for (int i = 0; i < length; i++) { 一样不变,一切都会正常工作。