2012-07-01 56 views
8

为什么我可以说一个类型字段具有混合到其中的另一个类的类的类型(只有特性可以在类中混合)?为什么可以在类型字段中的类中混合?

例子:

scala> class A 
defined class A 

scala> class B extends A 
defined class B 

B混合A是不允许的:

scala> new A with B 
<console>:10: error: class B needs to be a trait to be mixed in 
      new A with B 
         ^

但是,这是可能的:

scala> class E {type T = A with B} 
defined class E 

scala> new E 
res1: E = [email protected] 
+0

看起来像一个bug给我。 –

回答

3

这就是所谓的compound type并没有任何做与特质。它允许你表达一个类型是其他几种类型的子类型。

有关可能发生的更多信息,请参见“类型处理”一节中的Scala tag info

+0

这并没有回答这个问题:为什么这可能? –

+1

@RobinGreen:为什么不可能? '新A与B'表示* mixin *'B'与'A','类型T = A与B'意味着'T'类型为'A' *和*'B'。 – sschaef

+2

@Antoras - 问题是有效的。既然你不能_instantiate_混合两个类,你可以有两种类的复合类型的有用情况是什么?虽然整个系统仍然健全,但有人可能会争辩说,当在'A with B'中编译器已知这两种类型是指类时,它至少会发出警告。 –

6

mixin实例与复合类型定义之间有区别。 所有类型的第一A with B存在,并且是完全型B,唉它是Scala完全合法的写

val x: A with B = new B 

val y: Any with AnyRef with A with B = new B 

,因为它描述完全相同的类型。 您只是在可以分配给该类型变量的值的类型中引入限制。 这种限制当然总是适用于这种情况。

此外,你必须记住,斯卡拉不一定需要一个类型有人居住 - 即底部类型Nothing可能根本没有实例化。 但作为Nothing是每一个可以在Scala中表示类型的子类型它来写一个表达式等

def foo: AnyRef with AnyVal = sys.error("IMPOSSIBRU!") 

Nothing甚至有效是通过定义的AnyRef with AnyVal亚型从而该声明typechecks。

相关问题