多次混合相同特征的规则
我试图编写一些抽象代码,使其逐步变得更加复杂。它在其中一步就坏了。
第一步,更正
trait Base
trait C1 extends Base
trait Abst extends Base
trait Conc extends Abst with C1
第二步,更正
object BaseHolder {
trait Data
}
object C1Holder {
trait Data extends BaseHolder.Data
}
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
第三步,错误
trait BaseHolder {
trait Data
}
object BaseHolder extends BaseHolder
trait C1Holder extends BaseHolder {
trait Data extends super.Data
}
object C1Holder extends C1Holder
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
我得到了错误: 非法继承; Trait Con 继承了 Trait Data 的不同类型实例
这个错误意味着什么?有什么方法可以绕过它?
I was trying to write some piece of abstract code making it more complicate step by step. And it had broken at one of this steps.
1st step, correct
trait Base
trait C1 extends Base
trait Abst extends Base
trait Conc extends Abst with C1
2nd step, correct
object BaseHolder {
trait Data
}
object C1Holder {
trait Data extends BaseHolder.Data
}
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
3rd step, buggy error
trait BaseHolder {
trait Data
}
object BaseHolder extends BaseHolder
trait C1Holder extends BaseHolder {
trait Data extends super.Data
}
object C1Holder extends C1Holder
trait Abst extends BaseHolder.Data
trait Conc extends Abst with C1Holder.Data
I've got the error:
illegal inheritance; trait Con inherits different type instances of trait Data
What does this error means and is there any way to bypass it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
完整的错误消息是
它说
(object BaseHolder).Data
与(object C1Holder).Data
不一致,因为尽管后者符合(trait BaseHolder )#Data
,这比单例实例object BaseHolder
中的trait Data
不太具体。编辑。请注意,类型和值存在于不同的命名空间中,因此名称
BaseHolder
本身是不明确的,它可以引用对象的任一特征。但是,当引用类型时,“.”或“#”符号消除歧义:T#Data
始终表示 typeT
中的Data
类型成员>。例如,BaseHolder#Data
将引用特征BaseHolder
。x.Data
始终表示对象x
中的Data
类型成员。例如,BaseHolder.Data
将引用单例对象BaseHolder
。请注意,
trait BaseHolder
的两个实例x
和y
将具有不同的类型x.Data
和y .数据
;这就是路径依赖类型的工作原理。另请注意,object BaseHolder extends BaseHolder
只是trait BaseHolder
的一个特定实例。要编译代码,请确保
(trait C1Holder)#Data
实际上符合(object BaseHolder).Data
在此示例中,特征没有做太多事情,所以你可能只想选择
The full error message is
It's saying that
(object BaseHolder).Data
is not consistent with(object C1Holder).Data
since although the latter conforms to(trait BaseHolder)#Data
, this is less specific thantrait Data
in the singleton instanceobject BaseHolder
.Edit. Note that types and values live in different namespaces, so the name
BaseHolder
alone is ambiguous, it could refer to either the trait of the object. However, when referring to a type, the "." or "#" symbol disambiguates:T#Data
always means theData
type member in the typeT
. For example,BaseHolder#Data
would be referring to the traitBaseHolder
.x.Data
always means theData
type member in the objectx
. For example,BaseHolder.Data
would be referring to the singleton objectBaseHolder
.Note that two instances
x
andy
oftrait BaseHolder
will have different typesx.Data
andy.Data
; this is how path dependent types work. Also note thatobject BaseHolder extends BaseHolder
is just one particular instance oftrait BaseHolder
.To get your code to compile, make sure
(trait C1Holder)#Data
actually conforms to(object BaseHolder).Data
In this example, the traits aren't doing much, so you might want to just go with
您将外部特征视为内部特征的简单容器,就像对待包裹一样。然而,内部类和特征与其父类有更复杂的关系。
内部类和特征始终与父类的实例相关联。没有父实例就不可能创建内部类。实际上,内部类有一个隐藏的引用,指向父类的实例。
在您的情况下,特征 Data 与对象 BaseHolder 关联。然后 Trait Abst 扩展了 BaseHolder.Data,因此它也与对象 BaseHolder 关联。这意味着 Abst 将引用 BaseHolder 对象作为其父对象。
另一方面,C1Holder.Data 引用 C1Holder 作为其父级。因此,当您定义 Conc 时,它必须引用 BaseHolder 和 C1Holder 作为父级。但内在特质只能有一个父母。因此出现了错误。
You are treating outer traits as simple containers for your inner traits, almost like one would treat packages. However inner classes and traits have a more intricate relationship with their parent classes.
Inner classes and traits are always associated with an instance of the parent class. It is not possible to create an inner class without a parent instance. In practice inner classes have a hidden reference that points to an instance of the parent class.
In your case the trait Data is associated with the object BaseHolder. Then trait Abst extends BaseHolder.Data, so it is also associated with the object BaseHolder. That means that Abst will reference BaseHolder object as its parent.
On the other hand C1Holder.Data references C1Holder as its parent. So when you are defining Conc it must reference both BaseHolder and C1Holder as a parent. But an inner trait can only have ONE parent. Hence the error.