给定一个带有covariant
类型参数的类:
scala> class G[+A]
defined class G
以下列表显示List[G[Any]]
的最小上限。
scala> List(new G[Int], new G[String])
res1: List[G[Any]] = List(G@5aa360ea, G@6548bb7d)
然后,给定一个带有invariant
类型参数的类:
scala> class F[A]
defined class F
我看到List[F[_ >: String with Int]]
的最小上限(LUB)。
scala> List(new F[Int], new F[String])
res0: List[F[_ >: String with Int]] = List(F@6c4980d3, F@327bcebd)
一个更简单的示例显示了List[Any]
的LUB:
scala> List( (42 : Int), "foobar" )
res2: List[Any] = List(42, foobar)
请解释List
的{{1}}的LUB。
答案 0 :(得分:2)
G
在其类型参数A
上是协变。这意味着,对于任何类型A
和B
,如果A
是<{1>}的子类型,那么G
是G[A]
的子类型。让我们简单地写一下,使用G[B]
来表示A <:< B
是A
的子类型,然后是B
。
这意味着当我们有G[A] <:< G[B]
时,允许编译器将其推断为List(new G[Int], new G[String])
,因为List[Any]
和List[G[Int]] <:< List[G[Any]]
(从List[G[String]] <:< List[G[Any]]
开始在其类型参数上也是协变的。)
你可能已经知道了,但是对那些还没有的人来说,这是值得解释的。
List
对其类型参数F
不变,因此我们无法进行相同的扣除。好的,那么A
的类型是什么?由于List(new F[Int], new F[String])
不变,我们不能说F
或F[Int] <:< F[Any]
(因为它不是真的!)。所以它不是F[String] <:< F[Any]
那么编译器可以推断出什么?它唯一真正的选择是一些存在类型,因为它不能是List[F[Any]].
,或Any
,或其他任何不破坏协方差的东西。由于它正在寻找最小上限,它推断出一个存在类型,它由下面包含类型的复合(在String with Int
中)限定。也就是说,F
是某些无名字型,其下限 _ >: String with Int
。
或者,换句话说,我们知道我们有String with Int
List
个,但我们不知道每个类型中包含的是什么类型。只有F
中任何给定的F
是List
或F[Int]
,但就是这样。