关于Scala的类层次结构的问题:
在IntelliJ IDE中,我正在寻找Any
和AnyRef
的实现,但它们并不存在。
他们在哪里定义,我怎样才能看到他们的代码?
我在" Scala编程"
嗯......但最终不是==不直接调用equals的唯一情况是Java 盒装数字类,例如Integer或Long。在Java中,一个新的 即使对于原语,整数(1)也不等于新的Long(1) 值1 == 1L。由于Scala是比Java更常规的语言,因此 有必要通过特殊套管==来纠正这种差异 这些类的方法。
==
?他们是如何为Java的数字类做出特殊情况的呢?
答案 0 :(得分:8)
Any
,AnyRef
,Null
和Nothing
实际上并不存在;包含它们是为了使类型系统完整,但它们没有真正的表示。您可以找到a reference in Scala's repository,但正如它所说,这些实际上并不是为了文档和引导目的而编译和存在。 Scala的3 Any*
实际上是编译后的字节码中的java.lang.Object
。
此外,原始值类(Int
,Long
等)都被定义为final abstract
,这意味着它们实际上并不存在。他们所有的方法都是抽象的。
为了使一切看起来整洁,更重要的是,工作,编译器的工作就是伪造这些类型的存在并执行魔法以使它们完全结合在一起。这是允许==
进行空检查并正确处理值类型的原因,即使它是final
,因为编译器正在围绕它进行魔术。在new java.lang.Integer(5) == new java.lang.Long(5)
的情况下,归结为scala.runtime.BoxesRuntime.equalsNumNum(new java.lang.Integer(5), new java.lang.Long(5))
。
答案 1 :(得分:6)
语言拥有像这样的“神奇”部分是很正常的。无法用语言本身描述的部分。
明显的例子:您可以声明超类,也可以不声明超类,在这种情况下超类是AnyRef
。那么,你如何编写Any
,一个没有超类的类?好吧,你做不到。您可以扩展语言并允许程序员编写没有超类的类,但是您再也不能保证Any
只是 这样的类,因此您的继承层次结构将不再形成格子。但是,类型检查和类型推断规则依赖在继承层次结构上是格子。
因此,唯一合理的选择是定义Any
,而这种定义实际上无法在语言本身中表达。
Scala并不特别:例如,Java和Ruby的Object
存在同样的问题。
实际上,与其他主流语言相比,Scala有很多少这样的“神奇”......而 与底层主机生态系统(Scala-JVM的Java,Scala.js的ECMAScript,废弃的Scala.NET的CLI,假设的Scala-macOS的CoreFoundation等)。