加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala中的线性化顺序

发布时间:2020-12-16 09:32:42 所属栏目:安全 来源:网络整理
导读:在使用特征时,我难以理解Scala中的线性化顺序: class A { def foo() = "A"}trait B extends A { override def foo() = "B" + super.foo()}trait C extends B { override def foo() = "C" + super.foo()}trait D extends A { override def foo() = "D" + su
在使用特征时,我难以理解Scala中的线性化顺序:

class A {
  def foo() = "A"
}

trait B extends A {
  override def foo() = "B" + super.foo()
}

trait C extends B {
  override def foo() = "C" + super.foo()
}

trait D extends A {
  override def foo() = "D" + super.foo()
}

object LinearizationPlayground {
    def main(args: Array[String]) {

      var d = new A with D with C with B;
      println(d.foo) // CBDA????
  }    
}

它打印CBDA,但我不知道为什么。特征的顺序如何确定?

谢谢

解决方法

对线性化进行推理的直观方法是参考施工顺序和可视化线性层次结构。

你可以这样想:先建立基础类;特征是从左到右构建的,因为右侧的特征被添加“稍后”,因此“覆盖”先前的特征。然而,要构建一个特征,其基本特征必须首先构建(明显);当然,如果一个特征被构建,不再重建。现在,施工顺序与线性化相反。认为“基本”特征/类在线性层次结构中较高,并且层次结构中的特征较低,更接近作为线性化对象的类/对象。
线性化影响了“超级”在特征中如何解决:它将解析为最接近的基本特征(但在层次结构中更高)!

从而:

var d = new A with D with C with B;

A与D与C与B的线性化

>(层次结构顶部)A(首先构建为基类)
D的线性化

> A(以前不认为A)
> D(D扩展A)

> C的线性化

> A(以前不认为A)
> B(B延伸A)
> C(C延伸B)

> B的线性化

> A(以前不认为A)
> B(以前不认为B)

所以线性化是:A-D-B-C。
您可以将其视为线性层次结构,其中A是根(最高)并且首先构造,C是叶(最低)并最后构造。由于C最后构造,这意味着可以覆盖“以前”的成员。

给定这些直观的规则,d.foo调用C.foo,它返回一个“C”,后面是在B上解析的super.foo()(B的左边的特征,即线性化中的更高/之前),它返回一个“B”,然后是在D上解析的super.foo(),它返回一个“D”,后面是在A上解析的super.foo(),最后返回“A”。所以你有“CBDA”。

另一个例子,我准备了以下一个:

class A { print("A") }
trait H { print("H") }
trait S extends H { print("S") }
trait R { print("R ") }
trait T extends R with H { print("T") }
class B extends A with T with S { print("B") }

new B  // A R H T S B

// linearization as in reverse of construction order and thus rightmost "H" wins
// lin(B) = B >> lin(S) >> lin(T) >> lin(A)
//        = B >> (S >> H) >> (T >> H >> R) >> A
//        = B >> S >> T >> H >> R >> A

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读