覆盖类型界限时出现不兼容的类型错误

问题描述

在这里无法弄清为什么斯卡乐不满意(2.12):

trait A {
  type Self <: A
  type X <: Self
}

trait B extends A {
  override type Self <: B
  override type X = C // error: overriding type X in trait A with bounds <: B.this.Self
}

trait C extends B {
  override type Self = C
}

感觉像是由于依赖于路径的类型,但我不明白到底是什么错误,以及是否有解决它的好方法。

解决方法

CB的子类型,BA的子类型,因此CA的子类型,但是{ {1}}不是C的{​​{1}}或A的{​​{1}}的子类型。因此,您不能使用Self的{​​{1}}的{​​{1}}具有上限B(即Self的{​​{1}})来覆盖B不满足界限(即A的{​​{1}})。

X

Self的{​​{1}}等于A,但这并不意味着Self的{​​{1}}或C的{​​{ 1}}。

您可以使用下限修复编译

B

或者如果您是说Self的{​​{1}}是不是trait A { type Self <: A type X <: Self // implicitly[C <:< Self] // doesn't compile } trait B extends A { override type Self <: B // override type X = C // implicitly[C <:< Self] // doesn't compile } trait C extends B { override type Self = C } 的{​​{1}}而是C的{​​{1}}的子类型您可以使用投影类型指定它

Self

我猜误解是因为C s

A

当我们在Self的{​​{1}}中写入B时,实际上并不是指Self的{​​{1}},而是指实现的trait A { type Self <: A type X <: Self } trait B extends A { override type Self >: C <: B // >: C is added override type X = C } trait C extends B { override type Self = C } 。这是可能的,因为方法实现在运行时解析得较晚。但是类型会在编译时及早解析。所以当你写

A
X的上限中的

ASelf的{​​{1}},而不是实现的C

OOP原则说,在Self中,您can't refer specificallytrait A { type Self <: A type X <: C#Self // here } trait B extends A { override type Self <: B override type X = C } trait C extends B { override type Self = C } 的{​​{1}}(除非您实例化def)。但是您到处都可以使用类型为{{的类型}来具体引用trait A { def foo(): String = "A#foo()" def bar(): String = s"bar=A#bar(),foo=${foo()}" } trait B extends A { def foo(): String = "A#foo()" } trait C extends B { override def foo(): String = "C#foo()" } 的{​​{1}},foo()的{​​{1}},A的{​​{1}} 1}},bar()A

,

与米米·米汀(Dmytro Mitin)的回答稍有不同:如果您对B的定义是合法的,则可以进一步扩展

trait D extends B {
  override type Self = D  // satisfies Self <: B
}

但是X <: Self不会成立(X仍然是C,继承自B)。

更笼统地说,B中的约束应该暗示A中的约束,而实际上不是。添加>: C下限可以解决此问题。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...