为什么这很愉快地编译,
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
有解决方法吗?感谢。
答案 0 :(得分:2)
解决方法:强>
目前,我无法明确表达为什么它有效,但它有效:
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)
答案 1 :(得分:1)
似乎这是 Scala编译器错误, Scala编译器将检查子类的覆盖变量是否与超类的变量匹配 类型,按checkOverride方法
DerivedBar
&amp; OtherDerivedBar
正在检查Existential types
(这是通配符_
)是否与Bar.foo
匹配matchesType,但对于OtherDerivedBar
,它有 2 ExistentialType ,因此它会在sameLength比较方法失败,这会导致类型不匹配。
作为Andrey的解决方案,实际上编译器会将OtherDerivedBar
编译为[ClassArgsType, ExistentialType]
,这将传递sameLength
比较,因此不会抛出编译错误。
但实际上即使OtherDerivedBar
2 ExistentialType
它也应该是 Foo 的合法覆盖类型,因为:
type F = OtherDerivedFoo[_, _]
class OtherDerivedBar(override val foo: F) extends Bar(foo)
它也被编译。