考虑以下简单的Scala实验:
scala> trait A {class C;val c:C}
defined trait A
scala> object O1 extends A {val c=new C}
defined object O1
scala> object O2 extends A {val c=O1.c}
<console>:9: error: overriding value c in trait A of type O2.C;
value c has incompatible type
object O2 extends A {val c=O1.c}
根据Scala语言规范(SLS 5.1.4):
值O1.c
的类型应符合A.c
的类型,因为前者会覆盖后者。
问题1:
在SLS中指定了遵循的规则O1.c
的类型确实符合A.c
的类型?
那么为什么object O1 extends A {val c=new C}
根据SLS编译 ?
问题2:
在SLS中,指定了遵循的规则O1.c
的值不符合值O2.c
的类型?
换句话说,从哪个SLS规则 object O2 extends A {val c=O1.c}
不应该编译?
相关:根据SLS,为什么O2.c
的值类型应为O2.C
?
更新:
根据SLS,值O1.c
和抽象值成员A.c
的类型是什么?
答案 0 :(得分:1)
A.c
的类型为A#C
,O1.c
(更新:类型O1.C
,其中每个SLS为O1.type#C
)确实符合A#c
。
问题1:在O1
内,类型C
为O1.C
,new C
为new O1.C
(请参阅3.2.3中的类型标识符规则) 。 O1.C
符合O1.C
,因为它是等效的(因为等价是一致的)。
问题2:因为O1
不符合O2
,因为3.5.1或3.5.2中的规则都不会使O1
符合O2
}。因此,3.5.2中的类型预测规则并不适用。
构造函数调用根据5.1.1返回该类型的值。
(我真的不认为规范是学习这些东西的最佳方式;更好地了解事情如何先发挥作用)。