没有。这种情况下的线性化是
{<anonymous-local>, Incrementing, Doubling, BasicIntQueue, IntQueue, AnyRef, Any}
你可以:
- 只需阅读规范并说服自己一定是这样的
- 实现规范中算法的玩具版本,查看它为各种类定义输出的内容(这有点启发性,但主要是为了好玩)
阅读规范
section 5.1.2 of the Spec
准确地告诉您如何计算线性化。您似乎忘记在L(c_n) + ... + L(c_1) 中反转索引1 ... n。
如果您应用正确的公式,您将获得所涉及特征和基类的以下线性化:
IntQueue : {IntQueue, AnyRef, Any}
Doubling : {Doubling, IntQueue, AnyRef, Any}
Incrementing : {Incrementing, IntQueue, AnyRef, Any}
BasicIntQueue : {BasicIntQueue, IntQueue, AnyRef, Any}
如果你最终结合这些线性化来计算被实例化为incrThendoublingQueue 的匿名本地类的线性化:
<anonymous-local-class>, L(Incrementing) + L(Doubling) + L(BasicInt)
您获得了上面已经显示的线性化。因此,应按以下顺序调用方法:
与实际输出一致。
为了好玩重新实现线性化算法
这实际上是您可以从头开始轻松实现的规范中那些无依赖关系的 sn-ps 之一。这
替换连接的定义可以从
规范原样,它几乎是可运行的代码(除了带有箭头的有趣加号有点难以键入,而且我希望它作为列表中的中缀运算符):
implicit class ConcatenationWithReplacementOps[A](list: List[A]) {
def +^->(other: List[A]): List[A] = list match {
case Nil => other
case h :: t =>
if (other contains h) (t +^-> other)
else h :: (t +^-> other)
}
}
建模类声明C extends C1 with ... with Cn 也是
很简单:
case class ClassDecl(c: String, extendsTemplate: List[ClassDecl]) {
def linearization: List[String] = c :: (
extendsTemplate
.reverse
.map(_.linearization)
.foldLeft(List.empty[String])(_ +^-> _)
)
}
线性化的公式在这里实现为一种方法。注意reverse。
规范中给出的示例:
val any = ClassDecl("Any", Nil)
val anyRef = ClassDecl("AnyRef", List(any))
val absIterator = ClassDecl("AbsIterator", List(anyRef))
val richIterator = ClassDecl("RichIterator", List(absIterator))
val stringIterator = ClassDecl("StringIterator", List(absIterator))
val iter = ClassDecl("Iter", List(stringIterator, richIterator))
println(iter.linearization.mkString("{", ", ", "}"))
完全按照规范生成输出:
{Iter, RichIterator, StringIterator, AbsIterator, AnyRef, Any}
现在,这是您的示例的模型:
val intQueue = ClassDecl("IntQueue", List(anyRef))
val doubling = ClassDecl("Doubling", List(intQueue))
val incrementing = ClassDecl("Incrementing", List(intQueue))
val basicQueue = ClassDecl("BasicIntQueue", List(intQueue))
val incrThendoublingQueue = ClassDecl(
"<anonymous-local>",
List(basicQueue, doubling, incrementing)
)
println(incrThendoublingQueue.linearization.mkString("{", ", ", "}"))
它产生了我在上面已经展示过的线性化顺序:
{<anonymous-local>, Incrementing, Doubling, BasicIntQueue, IntQueue, AnyRef, Any}
一切似乎都按预期工作,没有理由写信给 Scala 用户。