为什么可以在类型字段中混合类?

Joh*_*ood 8 scala class

为什么我可以说类型字段的类型与另一个类混合在一起(当只有特征可以在类中混合时)?

例:

scala> class A
defined class A

scala> class B extends A
defined class B
Run Code Online (Sandbox Code Playgroud)

混合BA是不允许的:

scala> new A with B
<console>:10: error: class B needs to be a trait to be mixed in
             new A with B
                        ^
Run Code Online (Sandbox Code Playgroud)

但这是可能的:

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

scala> new E
res1: E = E@1f2bc83
Run Code Online (Sandbox Code Playgroud)

Mor*_*itz 6

mixin实例化和复合类型定义之间存在差异.首先,类型A with B存在并且正是类型B,唉它在scala中完全合法

val x: A with B = new B
Run Code Online (Sandbox Code Playgroud)

原样

val y: Any with AnyRef with A with B = new B
Run Code Online (Sandbox Code Playgroud)

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

此外,您必须记住,Scala不一定需要有人居住的类型 - 即底部类型Nothing可能根本不会被实例化.但是,作为Nothing可以在Scala中表达的每种类型的子类型,编写表达式甚至是有效的

def foo: AnyRef with AnyVal = sys.error("IMPOSSIBRU!")
Run Code Online (Sandbox Code Playgroud)

NothingAnyRef with AnyVal定义的子类型,因此声明类型检查.


kir*_*uku 3

这称为复合类型,与特质无关。它允许您表达某种类型是其他几种类型的子类型。

有关它们可能发生的更多信息,请参阅“类型处理”部分中的Scala 标记信息

  • @Antoras——这个问题是有效的。由于您无法_实例化_混合两个类,那么可以拥有两个类的复合类型的有用情况是什么?虽然整个系统仍然健全,但有人可能会争辩说,当编译器知道“A with B”中这两种类型引用类时,它至少会发出警告。 (2认同)
  • 嗯,是的,我也这么认为。另一方面,它是无害的,你最终不能做任何错事......但我不知道是否存在这样的声明可能有用的极端情况。 (2认同)