考虑一下:
object TypeProblem {
trait A {
type T
val set = Set[T]()
}
trait B {
def b()
}
trait FooBad { this: A =>
type T <: B
def x {
set.foreach(_.b())
}
}
trait FooOk { this: A =>
type MyT <: B
type T = MyT
def x {
set.foreach(_.b())
}
}
}
编译器抱怨值b不是FooBad.this.T的成员 那么为什么FooOk在我定义新类型MyT并将T分配给MyT的地方工作?
答案 0 :(得分:4)
编译器将FooBad
的自我类型扩展为FooBad with A
(这样您仍然可以访问自己定义的成员)。这意味着T
获取A
中的定义,而不是FooBad
中的定义,正如您所期望的那样。您可以通过更改FooBad
的定义来明确添加自己的类型来修复代码:
trait FooBad { this: A with FooBad =>
..
}
甚至更好地使用子类化
trait FooBad extends A {
..
}
我相信在大多数情况下,自我类型应该用普通的子类代替。它更容易理解,更不可怕,并且可以更好地封装。