Scala:“类型A = XXX”和“最终类型A = XX”之间的区别?

tri*_*oid 6 polymorphism inheritance scala abstract-type

假设我有抽象类型AA和具体类型XXX:

trait AA {
  type A = XXX
  final type B = XXX
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,在AA的任何子类中,都不能覆盖类型A和B,因此看来关键字final是完全多余的。这句话正确吗?

Bri*_*hon 7

很难证明它们是完全相同的,但是我要指出的是,它们减去了一些无用的怪癖。

无用的怪癖

首先也是最明显的是,它们给出不同的错误消息。但这还不是全部:从技术上讲,可以覆盖A,但是不能将其覆盖XXX

trait A1 extends AA {
  override type A = XXX  // Compiles, but doesn't really do anything.
}
Run Code Online (Sandbox Code Playgroud)

另一方面,您永远无法覆盖B

trait A2 extends AA {
  override type B = XXX  // Does not compile.
}
Run Code Online (Sandbox Code Playgroud)

有什么有用的区别吗?

再说一次,我要说的是没有。在对该问题是否可以覆盖类型字段的非常详细的回答中,StackOverflow用户0__注意到:

type T = C不可避免地进行修复T,这相当于制定方法final

现在,您可以轻松地看到必须禁止进一步“覆盖” T

接下来是一些解释,说明如果可以覆盖T其他类型,类型系统将如何不一致。有关详细信息,请参见该答案。