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(解决方案)还是给你(解释)打勾:/