天天看點

【轉載】了解scala中的Symbol

【轉載】了解scala中的Symbol

相信很多人和我一樣,在剛接觸Scala時,會覺得Symbol類型很奇怪,既然Scala中字元串都是不可變的,那麼Symbol類型到底有什麼作用呢?

簡單來說,相比較于String類型,Symbol類型有兩個比較明顯的特點:節省記憶體和快速比較。在進入正題之前,讓我們先來了解一下Java中String的intern()方法。

一、String的intern方法介紹

Oracle的開發文檔上講解的很詳細:String類内部維護一個字元串池(strings pool),當調用String的intern()方法時,如果字元串池中已經存在該字元串,則直接傳回池中字元串引用,如果不存在,則将該字元串添加到池中,并傳回該字元串對象的引用。執行過intern()方法的字元串,我們就說這個字元串被拘禁了(interned)。預設情況下,代碼中的字元串字面量和字元串常量值都是被拘禁的,例如:

String s1 = "abc";
String s2 =new String("abc");      

//傳回true

System.out.println(s1 == s2.intern());

同值字元串的intern()方法傳回的引用都相同,例如:

String s2 = new String("abc");
String s3 = new String("abc");      

//傳回true

System.out.println(s2.intern() == s3.intern());

//傳回false

System.out.println(s2 == s3);

二、Symbol類型的主要特點

下面接着介紹Symbol類型的兩個特點。

1. 節省記憶體

在Scala中,Symbol類型的對象是被拘禁的(interned),任意的同名symbols都指向同一個Symbol對象,避免了因備援而造成的記憶體開銷。而對于String類型,隻有編譯時确定的字元串是被拘禁的(interned)。Scala測試代碼如下:

val s = 'aSymbol
//輸出true
println( s == 'aSymbol)
//輸出true
println( s == Symbol("aSymbol"))      

2. 快速比較

由于Symbol類型的對象是被拘禁的(interned),任意的同名symbols都指向同一個Symbol對象,而不同名的symbols一定指向不同的Symbol對象,是以symbols對象之間可以使用操作符==快速地進行相等性比較,常數時間内便可以完成,而字元串的equals方法需要逐個字元比較兩個字元串,執行時間取決于兩個字元串的長度,速度很慢。(實際上,String.equals方法會先比較引用是否相同,但是在運作時産生的字元串對象,引用一般是不同的)

三、Symbol類型的應用

Symbol類型一般用于快速比較,例如用于Map類型:Map<Symbol, Data>,根據一個Symbol對象,可以快速查詢相應的Data, 而Map<String, Data>的查詢效率則低很多。

上一篇: USB的VID,PID