Scala 在 Java 的类型系统上叠加了一个非常优雅的类层次结构,从顶部的 Any 膨胀到 AnyRef 和 AnyVal 以分别覆盖 Java 的 Objects 和原语,然后最终收敛,将引用类型折叠为 Null 并将所有类型折叠为 Nothing。据我了解,Nothing 是一切事物的子类型;将 AnyRef/java.lang.Object 的所有子类型的子类型设为空。[见http://www.scala-lang.org/node/128 ]
然而,似乎有一些不规则之处,一些地方不能简单地将所有 Scala 类型视为无缝类型层次结构的元素。我觉得这很烦人,并想了解我可能会感到惊讶的地方。
到目前为止,我知道一些违规行为:
1) 虽然 Null 是 AnyRef 的子类型,但调用 null.isInstanceOf[AnyRef](或 AnyRef 的其他子类型)返回 false。我怀疑选择这与 Java 的 instanceof 运算符的行为一致。
2) 无论方差注释如何,一切都与 Nothing 是协变的。如果我有一个返回未标记为协变的类型 T 的方法,我可以重写该方法以返回 Nothing 类型。[注意:此说法是错误的,请参阅下面的答案和评论!]
3)我不能将 isInstanceOf 应用于类型 AnyVal [请参阅为什么 AnyVal 不能在 isInstanceOf 检查中使用?以及如何测试作为 AnyVal 的值?]
4) 询问某事是否 isInstanceOf[Null] 是非法的,这是一个完全连贯的问题(尽管不是特别必要,因为“myVar == null”会给出相同的答案)
Scala 的类型层次结构中是否还有其他不规则或特殊情况的示例?我觉得这些值得学习和理解,以避免不受欢迎的惊喜。