Scala 当值类型具有不同数量的类型参数时,如何重写值?

Scala 当值类型具有不同数量的类型参数时,如何重写值?,scala,scala-compiler,scala-2.12,Scala,Scala Compiler,Scala 2.12,为什么会这样, 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: Othe

为什么会这样,

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编译器将通过方法检查子类的重写变量是否与超类的变量类型匹配

对于
DerivedBar
OtherDerivedBar
它正在检查
存在类型
(这是通配符
)是否与
Bar.foo
type by匹配,但是对于
OtherDerivedBar
它有2存在类型,因此它在比较方法上会失败,这将导致类型不匹配

作为Andrey的解决方案,实际上编译器将
OtherDerivedBar
编译为
[ClassArgsType,existentitype]
,这将传递
samelelength
比较,因此不会引发编译错误

但实际上,即使是
OtherDerivedBar
也有2
存在类型
它也应该是Foo的合法覆盖类型,因为:

type F = OtherDerivedFoo[_, _]

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

它也已编译。

谢谢。想知道为什么会发生这种情况,以及为什么这个解决方案有效,我会很感兴趣的@Lasf为什么解决方案有效是很清楚的,还有什么不清楚为什么你的第二个案例没有。。。我个人并不觉得我自己的答案完全令人满意,这更像是一个快速解决方案。如果有人真的能解释这种行为,不要犹豫,接受更详细的答案。或者,如果你有良好的记忆力或不留下任何问题未解决的好习惯,现在就不接受我的答案,它可能会在周一早上以这种方式得到更多的关注。并可能将其标记为
scala编译器
?我不知道,打得好。现在还不能接受。。。如果几天后没有更好的事情发生,我会重新接受。再次感谢。FWIW,Andrey Tyukin使用我的框架翻译的解决方案是
类OtherDerivedBar(用OtherDerivedBoo[T,)覆盖val foo:(foo[T]和OtherDerivedBoo[T,)),对于某些{type T})扩展了Bar(foo)
非常感谢。现在我不确定是给Andrey(解决方案)还是给你(解释)打勾:/