Scala trait 线性推导
代码
class A{
def m(s:String) = println(s"A($s)")
}
trait B extends A{
override def m(s:String) = super.m(s"B($s)")
}
trait C extends A{
override def m(s:String) = super.m(s"C($s)")
}
trait D extends A{
override def m(s:String) = super.m(s"D($s)")
}
trait E extends C{
override def m(s:String) = super.m(s"E($s)")
}
trait F extends C{
override def m(s:String) = super.m(s"F($s)")
}
class G extends D with E with F with B{
override def m(s:String) = super.m(s"G($s)")
}
val x = new G
x.m("")
类图
第一种推导方式
- 从右往左,选择离G最远的trait,将该tiait从自身到父类从左往右放置
- 将此时线性化的结果中重复值去掉,原则是多个元素保留最右
- 在最右加入AnyRef和Any,完成构建
step | 结果 |
---|---|
1 | G B A |
2 | G B A F C A |
3 | G B A F C A E C A |
4 | G B A F C A E C A D A |
5 | G B F C E C D A |
6 | G B F E C D A |
7 | G B F E C D A AnyRef Any |
所以输出应该是:
A(D(C(E(F(B(G()))))))
第二种推导方式
- 从左往右,选择离G的trait最近的进行放置在左边,他的父类放在右边
- 依次将剩下的trait的也从左边开始放置,如果其父类已经出现在右边,则跳过
- 在最右加入AnyRef和Any,完成构建
step | 结果 |
---|---|
1 | G D A |
2 | G E C D A |
3 | G F E C D A |
4 | G B F E C D A |
5 | G B F E C D A AnyRef Any |
所以输出应该是:
A(D(C(E(F(B(G()))))))