[英]Scala F-Bounded Type Polymorphism
trait Account[T <: Account[T]]
case class BrokerAccount(total:BigDecimal) extends Account[BrokerAccount]
case class SavingsAccount(total:BigDecimal) extends Account[SavingsAccount]
Below function declaration and invocation works fine. 下面的函数声明和调用工作正常。
def foo1( xs: Array[T forSome { type T <: Account[T] }]):Array[T forSome { type T <: Account[T] }] = xs
foo1(Array(BrokerAccount(100),SavingsAccount(50)))
But below invocation gives compilation error. 但是下面的调用给出了编译错误。
def foo2( xs: List[T forSome { type T <: Account[T] }]):List[T forSome { type T <: Account[T] }] = xs
foo2(List(BrokerAccount(100),SavingsAccount(50)))
Error 错误
Main.scala:14: error: type mismatch; Main.scala:14:错误:类型不匹配;
found : List[Product with Serializable with Main.Account[_ >: Main.SavingsAccount with Main.BrokerAccount <: Product with Serializable with Main.Account[_ >: Main.SavingsAccount with Main.BrokerAccount <: Product with Serializable]]] 找到:列表[具有Main.Account可序列化的产品[_>:具有Main.BrokerAccount的Main.SavingsAccount <_:具有Main.BrokerAccount的具有序列化的产品[_>:具有Main.BrokerAccount <可具有序列化的产品]]]]
required: List[T forSome { type T <: Main.Account[T] }] foo2(List(BrokerAccount(100),SavingsAccount(50))) 必需:List [T forSome {类型T <:Main.Account [T]}] foo2(List(BrokerAccount(100),SavingsAccount(50)))
Can someone please explain me why compilation error occur in later case? 有人可以解释一下为什么以后会出现编译错误吗?
The key to the problem is variance - you're trying to return a contravariant value in covariant position (function return type). 问题的关键是方差-您正在尝试在协变位置(函数返回类型)中返回一个对数值。 Despite List
type is covariant in its argument ( trait List[+A]
), this essentially means its values are contravariant (can be assigned to a List of supertypes): 尽管List
类型在其参数中是协变的( trait List[+A]
),但这实际上意味着其值是协变的(可以分配给超类型的List):
val listOfSupers: List[_ >: Account[_]] = List(BrokerAccount(100), SavingsAccount(50))
What you're trying to return from the function foo2
is a complete contrary - List[_ <: Account[_]]
, thus the compiler error. 您试图从函数foo2
返回的是一个完全相反的结果foo2
List[_ <: Account[_]]
,因此是编译器错误。
If instead of List
you use Set
there, which is invariant in its type parameter just like Array
, everything will work fine. 如果使用Set
代替List
而不使用List
,则Set
的类型参数不变,就像Array
一样,一切都会正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.