Scala - 协方差
Scala - Covariance
根据协方差定义:
Q[+B] means that Q can take any class, but if A is a subclass of B,
then Q[A] is considered to be a subclass of 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
的子类?
现在,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@3e48e859, $anon@31ddd4a4))
scala> val b = List1[SomeB](new SomeB{},new SomeC{})
b: List1[SomeB] = List1(WrappedArray($anon@5e8c34a0, $anon@7c1c5936))
scala> val c: List1[SomeA] = b
c: List1[SomeA] = List1(WrappedArray($anon@5e8c34a0, $anon@7c1c5936))
scala> val c: List1[SomeA] = a
c: List1[SomeA] = List1(WrappedArray($anon@3e48e859, $anon@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@45acdd11, $anon@3f0d6038))
由于 List1[SomeB]
中的所有元素都是 SomeA
的子类型(因为 SomeB
扩展了 SomeA
),您可以简单地传递 List1[SomeB]
其中 [=预计 15=]。
根据协方差定义:
Q[+B] means that Q can take any class, but if A is a subclass of B, then Q[A] is considered to be a subclass of 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
的子类?
现在,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@3e48e859, $anon@31ddd4a4))
scala> val b = List1[SomeB](new SomeB{},new SomeC{})
b: List1[SomeB] = List1(WrappedArray($anon@5e8c34a0, $anon@7c1c5936))
scala> val c: List1[SomeA] = b
c: List1[SomeA] = List1(WrappedArray($anon@5e8c34a0, $anon@7c1c5936))
scala> val c: List1[SomeA] = a
c: List1[SomeA] = List1(WrappedArray($anon@3e48e859, $anon@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@45acdd11, $anon@3f0d6038))
由于 List1[SomeB]
中的所有元素都是 SomeA
的子类型(因为 SomeB
扩展了 SomeA
),您可以简单地传递 List1[SomeB]
其中 [=预计 15=]。