不知道为什么 scalac 在这里不开心(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
}
感觉是因为依赖于路径的类型,但我不明白到底是什么问题以及是否有好的方法来解决它。
最佳答案
C
是B
的子类型,B
是A
的子类型,所以C
是 A
的子类型,但 C
不是 A
的 Self
或 B
的 Self
。所以你不能覆盖(在B
中)A
的X
有上限Self
(即A
的 Self
)与 C
不满足界限(即 B
的 Self
)。
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
}
C
的 Self
等于 C
但这并不意味着 A
的 Self
或 B
的 Self
可以。
您可以使用下限修复编译
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
不是 A
的 Self
的子类型,而是C
的 Self
你可以用 type projection 指定这个
trait 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
}
我猜误会是因为 def
s
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()"
}
当我们在 A
的 bar()
中写 foo()
时,我们实际上指的不是 A
的 foo()
而是实现的 foo()
。这是可能的,因为方法实现在运行时被延迟解析。但是类型是在编译时提前解决的。所以当你写
trait A {
type Self <: A
type X <: Self
}
X
上界的Self
是A
的Self
,不是实现的Self
.
OOP 原则说,在 A
里面你 can't refer specifically到 C
的 foo()
(除非你实例化 C
)。但是你可以到处特指A
的Self
、B
的Self
、C
的 Self
类型投影 A#Self
、B#Self
、C#Self
。
关于scala - 覆盖类型边界时出现不兼容的类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63751517/