当值类型具有不同数量的类型参数时如何覆盖值?
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
比较,所以没有将抛出编译错误。
但实际上即使 OtherDerivedBar
有 2 ExistentialType
它也应该是 Foo 的合法覆盖类型,自:
type F = OtherDerivedFoo[_, _]
class OtherDerivedBar(override val foo: F) extends Bar(foo)
也编译了
为什么这样顺利编译,
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
比较,所以没有将抛出编译错误。
但实际上即使 OtherDerivedBar
有 2 ExistentialType
它也应该是 Foo 的合法覆盖类型,自:
type F = OtherDerivedFoo[_, _]
class OtherDerivedBar(override val foo: F) extends Bar(foo)
也编译了