我试图理解为什么当我在MyModel中为T使用更高种类的类型参数时,下面的代码为何无法编译
abstract class Model[M <: Model[M]]
class MyModel[T] extends Model[MyModel[T]]
class Bar[TModel <: Model[TModel]]
object Foo extends App {
new Bar[MyModel[_]]
}
但是如果我将其更改为new Bar[MyModel[Any]]
,它将进行编译。为什么会这样?
答案 0 :(得分:4)
Bar[MyModel[_]]
is Bar[MyModel[X] forSome {type X}]
。
(不要与Bar[MyModel[X]] forSome {type X}
或Bar[MyModel[X forSome {type X}]]
(后者is just Bar[MyModel[Any]]
混淆。这是三种不同的类型。)
Bar[MyModel[X] forSome {type X}]
(又名Bar[MyModel[_]]
)无法编译,因为MyModel[X] forSome {type X}
(又名MyModel[_]
)不满足Bar
的条件{{1} }。实际上,您可以检查
TModel <: Model[TModel]
不编译(与implicitly[(MyModel[X] forSome {type X}) <:< Model[MyModel[X] forSome {type X}]]
左边的X
和<:<
右边的X
无关)。 The thing is表示<:<
位于左侧MyModel[X] forSome {type X}
的存在类型MyModel[X1]
未连接到右侧的Model[MyModel[X] forSome {type X}]
(对于不变Model
(从class MyModel[T] extends Model[MyModel[T]]
得出MyModel[X1] <: Model[MyModel[X1]]
(1),还有MyModel[X1] <: (MyModel[X] forSome {type X})
(2),但是对于不变的Model
,我们不能将Model
应用于后者“不平等”)。
但是,如果您使Model
协变abstract class Model[+M <: Model[M]]
,那么我们可以将Model
应用于“不等式”(2),因此Model[MyModel[X1]] <: Model[MyModel[X] forSome {type X}]
以及与(1)一起得到{ {1}}的传递性。因此MyModel[X1] <: Model[MyModel[X] forSome {type X}]
的条件得到满足,并且Bar
得以编译。
new Bar[MyModel[_]]
之所以编译,是因为Bar[MyModel[Any]]
满足MyModel[Any]
的条件Bar
。确实TModel <: Model[TModel]
是因为MyModel[Any] <: Model[MyModel[Any]]
(您可以检查
class MyModel[T] extends Model[MyModel[T]]
编译)。