gpt4 book ai didi

Scala可堆叠特征

转载 作者:行者123 更新时间:2023-12-04 08:04:20 25 4
gpt4 key购买 nike

对于下面的代码,据我所知,表达式的线性化

新E与D与C与B

是E-> C-> B->D。因此,代码中不应该使用表达式d.foo()

下面评估为ECBD而不是CBDE。我想念什么?

    trait A {
def foo(): String = ""
}

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

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

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

class E extends A{
override def foo() = "E"
}

var d = new E with D with C with B;
d.foo() //prints CBDE

我注意到,如果我有一个像下面这样的F类
class F extends A with D with C with B{
override def foo() = "F" + super.foo()
}

并做
new F().foo

它显示“FCBD”

对我来说似乎有点矛盾,因为F类以与表达式相同的方式混合,但是具有不同的打印顺序

最佳答案

new E with D with C with B的第一种情况可以完美地解释here。它的线性化是EDBC,所以当您调用d.foo()时,它

  • 首先调用C#foo()
  • 然后B#foo()
  • 然后D#foo()
  • ,最后是E#foo()

  • 如果将 E作为特征并在最后混合使用: val d = new D with C with B with E,则 d.foo()将仅返回 "E",因为特征 E是线性化中的“最后一个”,并且仅覆盖 foo
    F的情况有所不同,因为您将 foo定义为 "F" + super.foo(),并且在这种情况下 superA with D with C with B,其线性化是 ADBC,因此 new F().foo()-首先打印 "F"
    -然后是 super.foo(),即 "CBD"

    顺便说一句,尝试更改 A#foo()以返回 "A",然后您会看到,在 E中,您覆盖了A的 foo,因此 "A"不出现在结果中,而在 F中,它是 "FCBDA"

    关于Scala可堆叠特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40579694/

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