假设我有两个类,其参数化类型具有相同的标识符
trait A {
type O
def f(a: Int, os: Seq[O]): Int
}
trait B {
type O
def g(a: Int, o: O): Int = { h1(o) + h2(a) }
def h1(o: O): Int
def h2(a: Int): Int = {a/2}
}
我想创建一个子类来将两者“结合”
trait C extends A with B {
def f(a: Int, os: Seq[O]): Int = {
os.map{ o => g(a, o) }.sum
}
}
最后,我创建了一个 C 实现
class D extends C {
type O = Int
def h1(o: O): Int = {5 * o}
}
在编写C
时,我还不知道O
是什么类型——但是,我想限制A.O == B.O
使得在 A.f
的实现中使用 B.g
是“有意义的”。我尝试实现这个,令人惊讶的是 Scala 似乎假设只有一种 type O
val d = new D
println(d.f(1, Seq(1,2,3)))
对我来说,这似乎是不正确的 - 为什么 A.O
和 B.O
应该同意?
编辑 我还想指出,如果您像这样对 O 施加约束,
case class Z()
case class Z1() extends Z
case class Z2() extends Z1
trait A {
type O <: Z
}
trait B {
type O >: Z2
}
class D extends C {
type O = Z1
编译将失败。但是,如果你用这个来代替,
trait A {
type O <: Z
}
trait B {
type O <: Z1
}
class D extends C {
type O = Z2
编译成功,一切正常。
最佳答案
我认为 Scala 总是“结合”特征的成员(类型成员和值成员),当两者混合时:
trait A { type T = Int }
trait B { type T = String }
object C extends A with B
给出
overriding type T in trait A, which equals Int; type T in trait B, which equals String needs `override' modifier
(这就是 Scala 处理多重继承问题的方式——无论一个标识符混合多少次,它都只存在一次)。
关于Scala:抽象类型和 Mixin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8102503/