gpt4 book ai didi

scala - 覆盖类型边界时出现不兼容的类型错误

转载 作者:行者123 更新时间:2023-12-03 23:34:00 27 4
gpt4 key购买 nike

不知道为什么 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
}

感觉是因为依赖于路径的类型,但我不明白到底是什么问题以及是否有好的方法来解决它。

最佳答案

CB的子类型,BA的子类型,所以C A 的子类型,但 C 不是 ASelfBSelf。所以你不能覆盖(在B中)AX有上限Self(即ASelf)与 C 不满足界限(即 BSelf )。

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
}

CSelf 等于 C 但这并不意味着 A SelfBSelf 可以。

您可以使用下限修复编译

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
}

或者如果你的意思是 AX 不是 ASelf 的子类型,而是CSelf 你可以用 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
}

我猜误会是因为 defs

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()"
}

当我们在 Abar() 中写 foo() 时,我们实际上指的不是 Afoo() 而是实现的 foo()。这是可能的,因为方法实现在运行时被延迟解析。但是类型是在编译时提前解决的。所以当你写

trait A {
type Self <: A
type X <: Self
}
X上界的

SelfASelf,不是实现的Self .

OOP 原则说,在 A 里面你 can't refer specificallyCfoo()(除非你实例化 C)。但是你可以到处特指ASelfBSelfCSelf 类型投影 A#SelfB#SelfC#Self

关于scala - 覆盖类型边界时出现不兼容的类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63751517/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com