【问题标题】:Scala F-Bounded Type PolymorphismScala F 有界类型多态性
【发布时间】:2016-09-22 18:39:21
【问题描述】:
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: 错误:类型不匹配;
找到:列表[带有可序列化的 Main.Account 的产品 [_ >:带有 Main.BrokerAccount 的 Main.SavingsAccount :带有 Main.BrokerAccount 的 Main.SavingsAccount 必需:List[T forSome { type T <: main.account foo2>

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

【问题讨论】:

    标签: scala scala-collections


    【解决方案1】:

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

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

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

    如果你在那里使用Set而不是List,它的类型参数是不变的,就像Array一样,一切都会正常工作。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-09
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    相关资源
    最近更新 更多