0

我试图理解为什么当我在 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]]它将编译。为什么是这样 ?

4

1 回答 1

4

Bar[MyModel[_]] Bar[MyModel[X] forSome {type X}]

(不应与Bar[MyModel[X]] forSome {type X}或混淆Bar[MyModel[X forSome {type X}]],后者只是 Bar[MyModel[Any]]。这是三种不同的类型。)

Bar[MyModel[X] forSome {type X}](aka Bar[MyModel[_]]) 无法编译,因为MyModel[X] forSome {type X}(aka MyModel[_]) 不满足Bar'condition TModel <: Model[TModel]。确实,您可以检查

implicitly[(MyModel[X] forSome {type X}) <:< Model[MyModel[X] forSome {type X}]]

不编译(X从左到右<:<X相关<:<)。问题是左侧存在类型的skolemization 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)一起MyModel[X1] <: Model[MyModel[X] forSome {type X}]通过传递性给出。满足soBar的条件并new Bar[MyModel[_]]编译。

Bar[MyModel[Any]]MyModel[Any]因为满足Bar条件所以编译TModel <: Model[TModel]。确实MyModel[Any] <: Model[MyModel[Any]]是因为class MyModel[T] extends Model[MyModel[T]](你可以检查一下

implicitly[MyModel[Any] <:< Model[MyModel[Any]]]

编译)。

于 2020-05-09T19:57:49.987 回答