当值类型具有不同数量的类型参数时如何覆盖值?

How to override value when value types have a different number of type parameters?

为什么这样顺利编译,

class Foo[T]

class DerivedFoo[T] extends Foo[T]

class Bar(val foo: Foo[_])

class DerivedBar(override val foo: DerivedFoo[_]) extends Bar(foo)

而这不是?

class OtherDerivedFoo[T, U] extends Foo[T]

class OtherDerivedBar(override val foo: OtherDerivedFoo[_, _]) extends Bar(foo)
//error: value foo overrides nothing

有解决办法吗?谢谢

解决方法:

目前,我不太清楚为什么它有效,但它有效:

import scala.language.existentials
class DerivedFoo2[T, U] extends Foo[T]
class DerivedBar2(
  override val foo: (Foo[X] with DerivedFoo2[X, _]) forSome { type X }
) extends Bar(foo)

(我已将 OtherDerivedFoo 替换为 DerivedFoo2,请参阅下面的重命名通知)

重命名

我已将 类 重命名如下,以强调两种情况之间的相似之处,并缩短解决方法的代码:

假设你有

class Foo[T]
class Bar(val foo: Foo[_])

这样编译:

class DerivedFoo1[T] extends Foo[T]
class DerivedBar1(override val foo: DerivedFoo1[_])    extends Bar(foo)

但这不是:

class DerivedFoo2[T, U] extends Foo[T]
class DerivedBar2(override val foo: DerivedFoo2[_, _]) extends Bar(foo)

似乎这是一个 Scala 编译器错误Scala 编译器 将检查子类的 override变量匹配超类的 variable type,通过 checkOverride 方法,

对于 DerivedBar & OtherDerivedBar 它正在检查 Existential types(即通配符 _)是否与 Bar.foo 类型匹配 matchesType, but for OtherDerivedBar it has 2 ExistentialType, so it will fail on sameLength比较方法,这会导致类型不匹配。

作为Andrey的解决方案,实际上编译器会将OtherDerivedBar编译为[ClassArgsType, ExistentialType],这将传递sameLength比较,所以没有将抛出编译错误。

但实际上即使 OtherDerivedBar2 ExistentialType 它也应该是 Foo 的合法覆盖类型,自:

type F = OtherDerivedFoo[_, _]

class OtherDerivedBar(override val foo: F) extends Bar(foo)

也编译了