scala:Scala的原始类型是如何实现的

  这些都是如何实现?实际上Scala以和Java同样方式存储整数:把它当作32位这对在JVM上效率以及和Java库互操作性方面来说都很重要标准操作如加法或乘法都被实现为原始操作然而当整数需要被当作(Java)对象看待时候Scala使用了“备份”类java.lang.Integer如在整数上toString思路方法或者把整数赋值给Any类型变量时就会这么做需要时候Int类型整数能被透明转换为java.lang.Integer类型“装箱整数”

  所有这些听上去都近似Java5里自动装箱并且它们确很像不过有个关键差异Scala里装箱比Java里更少看见尝试下面Java代码:

// Java代码  
boolean isEqual( x, y) {  
  x  y;  
}  
.out.prln(isEqual(421,421));  


  你当然会得到true现在把isEqual参数类型变为java.lang.Integer(或Object结果都样):

// Java代码  
boolean isEqual(Integer x, Integery) {  
  x  y;  
}  
.out.prln(isEqual(421,421));  


  你会发现你得到了false!原因是数421被装箱了两次因此参数x和y是两个区别对象

  在引用类型上表示引用相等而Integer是引用类型所以结果是false这是展示了Java不是纯面向对象语言个方面我们能清楚观察到原始类型和引用类型的间差别

  现在在Scala里尝试同样实验:

scala>def isEqual(x:Int, y:Int) = x  y  
isEqual:(Int,Int)Boolean  
scala>isEqual(421,421)  
res10:Boolean = true 
scala>def isEqual(x:Any, y:Any) = x  y  
isEqual:(Any,Any)Boolean  
scala>isEqual(421,421)  
res11:Boolean = true 


  实际上Scala里相等操作被设计为透明参考类型代表东西对值类型来说就是自然(数学或布尔)相等对于引用类型被视为继承自Objectequals思路方法别名这个思路方法被地定义为引用相等但被许多子类重载实现它们种族相等概念这也意味着Scala里你永远也不会落入Java知名有关字串比较陷阱Scala里字串比较以其应有方式工作:

scala>val x = "abcd".sub(2)  
x:java.lang.String = cd  
scala>valy="abcd".sub(2)  
y:java.lang.String=cd  
scala>xy  
res12:Boolean=true 


  Java里x和y比较结果将是false员在这种情况应该用equals不过它容易被忘记

  然而有些情况你需要使用引用相等代替用户定义相等例如某些时候效率是首要原因你想要把某些类哈希合并:hash cons然后通过引用相等比较它们例子 为这种情况类AnyRef定义了附加eq思路方法它不能被重载并且实现为引用相等(也就是说它表现得就像Java里对于引用类型那样)同样也有个eq反义词被称为ne例如:

scala>val x =  String("abc")  
x:java.lang.String = abc  
scala>val y =  String("abc")  
y:java.lang.String = abc  
scala>x  y  
res13:Boolean = true 
scala>x eq y  
res14:Boolean = false 
scala>x ne y  
res15:Boolean = true 


  Scala相等性会在第28章中讨论

Tags:  scalajava scala语言 netbeansscala scala

延伸阅读

最新评论

发表评论