2016-08-16 64 views
4

是什么val a=new String("Hello")val a="Hello"之间比较Scala中

实施例的区别是:

val a="Hello" 
val b="Hello" 
a eq b 
res:Boolean=True 

类似地:

val a=new String("Hello") 
val b=new string("Hello") 
a eq b 
res:Bolean=False 

回答

12

eq比较存储器的引用。

字符串文字被放在一个字符串常量池中,所以在第一个例子中它们共享相同的内存引用。这是comes from Javascala.String构建在java.lang.String之上)的行为。

在第二个示例中,您在运行时分配两个实例,所以当您比较它们时,它们位于不同的内存位置。

这是完全一样的Java,所以你可以参考这个答案详细信息:What is the difference between "text" and new String("text")?

现在,如果你想比较它们的值(相对于它们的内存的引用),你可以使用== (或equals)在斯卡拉。

实施例:

val a = new String("Hello") 
val b = new String("Hello") 
a eq b // false 
a == b // true 
a equals b // true 

这是比Java,其中==是行为类似Scala中eq操作者不同。

另请注意,==equals与处理null值(通常建议==)的处理方式略有不同。更多关于这个问题:Whats the difference between == and .equals in Scala?

+0

“字符串文字被放在一个字符串常量池” - 你可以提供任何来源?我试图在Scala语言规范中找到一个引用,但在['String']部分没有任何内容(http://scala-lang.org/files/archive/spec/2.11/01-lexical-syntax。 HTML#字符串常量)秒。 *在['Symbol']部分显式引用了汇集(http://scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#symbol-literals) (“Symbol的伴侣对象的'apply'方法缓存'Symbol'的弱引用,从而确保相同的符号文字是...... –

+0

...等价于参考相等。”),所以类似的事实是*没有*文档的'字符串'似乎是一个*故意的*遗漏,而不是一个简单的疏忽,或者换句话说,斯卡拉设计者*不*保证'字符串'共同保证'符号'符号单曲。 –

+0

它不在Scala语言规范中,因为它来自[JLS§3.10.5](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls- 3.10.5),其行为在[JVM规范5.1](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html)中实现。常用术语是字符串“interning”。请参阅下面的答案。 –

0

首先eq(和其相反的ne)用于所谓的引用相等。

您观察到的行为是由技术上称为字符串实习的结果,并且是Java的继承行为。 Scala在引擎盖下使用java.util.String。您可以在REPL中观察到这一点:

scala> val s = "Hello World!" 
s: String = Hello World! 

scala> s.isInstanceOf[java.lang.String] 
res1: Boolean = true 

You can see a general explanation of eq, ne, and == here

To learn about JVM string interning see this Wikipedia article