2016-08-16 66 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