我有以下关于类和特征的声明
class C
class D extends C
trait T extends C
trait U extends D with T
以及以下任务:
val x1:C with T with U = new D with U
val x2:D with T = new C with U
val x3:D with T = new U
val x4:U = new D with T
第一个作业有效,其他作业无效。 我想了解两种情况的原因。
据我了解,线性化如下(->
表示extends
):
C with T with U
:U -> D -> T -> C
D with U
:U -> T -> D -> C
D with T
:T -> D -> C
C with U
:U -> T -> D -> C
我绘制了类型层次结构以获取更多见解:
我的理解如下:
x1
:之所以起作用,是因为线性化的类型相同(D
和T
的顺序对该类型并不重要)x2
:因为...不起作用?x3
:由于无法实例化特征而无法使用x4
:不起作用,因为D with T
是U
第2个是我遇到的问题。它应该可以在IMO上工作,因为D with T
的线性化为D -> T -> C
,这是C with U
的线性化(即U -> T -> D -> C
)的超类型。
要么我假设混合特征/类的顺序并不重要(但是为什么要编译第一个赋值?),或者我的线性化是错误的??
您能帮我吗?
答案 0 :(得分:3)
问题是new C with U
无效; val x2
的类型无关紧要。
特征U
扩展了D
,这意味着它只能应用于D
的子类。由于C
不是D
的子类,因此无法对其应用特征。
扩展类的特征类似于自我类型,但有一些细微的差异。有关更多信息,请参见This answer。