【问题标题】:Scala - CovarianceScala - 协方差
【发布时间】:2016-08-24 10:39:17
【问题描述】:

根据协方差定义:

Q[+B] 表示 Q 可以取任何类,但如果 A 是 B 的子类, 那么 Q[A] 被认为是 Q[B] 的子类。

让我们看下面的例子:

trait SomeA
trait SomeB extends SomeA
trait SomeC extends SomeB

case class List1[+B](elements: B*) 

val a = List1[SomeA](new SomeA{},new SomeB{})
val b = List1[SomeB](new SomeB{},new SomeC{})

一切都很好,但我不明白为什么List1[SomeB]List1[SomeA] 的子类,或者换句话说为什么b 是a 的子类?

【问题讨论】:

标签: scala covariance scala-generics


【解决方案1】:

现在,List1[SomeB]List1[SomeA] 的子类,这意味着您可以将第一个放在需要后者的地方。

scala> case class List1[+B](elements: B*)

scala> val a = List1[SomeA](new SomeA{},new SomeB{})
a: List1[SomeA] = List1(WrappedArray($anon$2@3e48e859, $anon$1@31ddd4a4))

scala> val b = List1[SomeB](new SomeB{},new SomeC{})
b: List1[SomeB] = List1(WrappedArray($anon$2@5e8c34a0, $anon$1@7c1c5936))

scala> val c: List1[SomeA] = b
c: List1[SomeA] = List1(WrappedArray($anon$2@5e8c34a0, $anon$1@7c1c5936))

scala> val c: List1[SomeA] = a
c: List1[SomeA] = List1(WrappedArray($anon$2@3e48e859, $anon$1@31ddd4a4))

如果它是不可能的,请参阅:

scala> case class List1[B](elements: B*)
defined class List1

scala> val c: List1[SomeA] = b
<console>:16: error: type mismatch;
 found   : List1[SomeB]
 required: List1[SomeA]
Note: SomeB <: SomeA, but class List1 is invariant in type B.
You may wish to define B as +B instead. (SLS 4.5)
       val c: List1[SomeA] = b
                             ^

scala> val c: List1[SomeA] = a
c: List1[SomeA] = List1(WrappedArray($anon$2@45acdd11, $anon$1@3f0d6038))

【讨论】:

    【解决方案2】:

    由于List1[SomeB] 中的所有元素都是SomeA 的子类型(如SomeB 扩展SomeA),因此您可以简单地传递List1[SomeB],其中需要List1[SomeA]

    【讨论】:

      猜你喜欢
      • 2016-10-16
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      • 2022-01-21
      相关资源
      最近更新 更多