Scala中的自类型继承

9

假设我有以下特点:

trait A

trait B { this: A => }

trait C extends B // { this: A => }

编译错误:illegal inheritance; self-type C does not conform to B's selftype B with A
如果我取消注释自类型注释,编译器就会很高兴地通过,这是意料之中的。
我认为为什么C也需要这个自类型显而易见。但我不明白为什么它不能从A那里“继承”,如果编译器已经能够确定它是必需的?
我认为在使用具有复杂层次结构的自类型时,它可以减少冗余,特别是如果您混合了大量特性,每个特性都有自己的自类型。
我猜也许有一个好的原因解释当前的行为,只是我找不到/弄清楚是什么。
起初,我以为它可能与混入线性化有关,但在我混入更多特性和更复杂的自类型的情况下,它似乎对我没有影响。
在某些情况下会导致歧义吗?如果是这样,为什么不能在没有歧义的情况下工作?
还是与正确实现相关的一些困难有关?
我可以找到一些关于这个主题的讨论(例如self type is not inherited),但它们大多只是陈述问题,并得出这就是现状,没有太多的解释和/或解决方案(如果存在)。
1个回答

1
trait C extends B with A

不是唯一的解决方案。你也可以有

trait AA extends A
trait C extends B with AA

也就是说,所有继承了 A 接口的都被接受。如果你必须依赖于具体实现,那么你会选择一个 mixin;如果实现由用户决定或者你有充分的理由不在 trait 中指定 mixin(例如为了减少依赖问题),那么你会将其作为自身类型。


1
我认为我清楚地知道在特质中混合和将其作为自类型之间的区别。我的问题是:假设我想要以自类型和混合的方式使用先前的特质,并且编译器可以确定我需要(至少)A作为C的自类型,为什么它不能自动“添加”它呢? - Sandor Murakozi
我认为在许多情况下这是不可取的,因为它将会编译而不给你特殊化类的机会。当当前作用域中没有 A 时,该怎么办?我认为这会让人困惑,应该明确继承和混合。此外,当你想要节省打字时,你可以定义一个 trait CA extends C with A 并使用它。 - Debilski
1
Debilski,你误解了问题。OP想要“trait C extends B”等价于“trait C extends B {this: A => }”,而不是“trait C extends B with A”。 - Blaisorblade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接