为什么String与Scala中的Int,Boolean,Byte ...不同?

sab*_*abi 5 scala

因为我知道一点点的Java,我试图在每一个Scala代码一些Java类型,如使用java.lang.Integer,java.lang.Character,java.lang.Boolean...等等.现在人们告诉我"不!对于Scala中的所有东西都有自己的类型,Java的东西会起作用 - 但你应该总是喜欢Scala类型和对象".

好的,我现在看到,Scala中有Java中的所有东西.不知道为什么最好使用例如Scala Boolean而不是Java Boolean,但很好.如果我看我看的类型scala.Boolean,scala.Int,scala.Byte...然后我看着字符串,但它不是scala.String,(以及它甚至没有java.lang.String 混淆),它只是一个字符串.但我想我应该使用直接来自scala的所有内容.也许我不正确理解scala,有人可以解释一下吗?

Vla*_*eev 11

首先,"它甚至不是java.lang.String"语句也不完全正确.普通String名称来自Predefobject中定义的类型别名:

type String = java.lang.String
Run Code Online (Sandbox Code Playgroud)

并且Predef在每个Scala源中导入了内部,因此您使用String而不是完整java.lang.String,但实际上它们是相同的.

java.lang.String是JVM以特殊方式处理的非常特殊的类.正如@ pagoda_5b所说,它被声明为final,它不可能扩展它(事实上这很好),因此Scala库提供了一个RichString包含额外操作的包装器()和String -> RichString默认情况下可用的隐式转换.

但是,稍有不同的情况有Integer,Character,Boolean等你看,即使String是由JVM,它仍然是一个普通类,其实例是普通的对象特殊处理.从语义上讲,它与List课程没有什么不同.
原始类型还有另一种情况.Java的int,char,boolean类型不是类,而这些类型的值不是对象.但Scala是完全面向对象的语言,没有原始类型.可以在java.lang.{Integer,Boolean,...}任何需要相应类型的地方使用,但由于装箱,这将是非常低效的.
因此,Scala需要一种在面向对象的设置中呈现Java原始类型的方法,等等scala.{Int,Boolean,...}课程介绍.这些类型通过Scala编译器进行特殊处理 - 当scalac遇到其中一个类时,会生成使用原语的代码.它们还扩展了AnyVal类,这会阻止您将null这些类型用作值.这种方法解决了效率问题,java.lang.{Integer,Boolean,...}在真正需要装箱的地方留下了类,并且还提供了使用其他主机系统原语(例如.NET运行时)的优雅方法.