2012-11-27 48 views
4

因爲我知道一點點的Java,我試圖在每一個Scala代碼的一些Java類型使用像java.lang.Integerjava.lang.Characterjava.lang.Boolean ......等等。現在人們告訴我:「不!對於Scala中的所有東西都有一個自己的類型,Java的東西可以工作 - 但是您應該總是喜歡Scala類型和對象。爲什麼String與Int,Boolean,Byte ...在scala中不同?

好的,現在我明白了,Java中的Scala中有一切。不知道爲什麼最好使用例如Scala布爾值而不是Java布爾值,但是很好。如果我看的類型我看到scala.Booleanscala.Intscala.Byte ...然後我看着字符串,但它不是scala.String,(以及它甚至沒有java.lang.String迷惑)它只是一個字符串。但我認爲我應該使用來自scala的所有內容。也許我不正確地理解scala,有人可以解釋一下嗎?

+4

可能是這個主題會幫助你理解這一刻:http://stackoverflow.com/questions/6559938/scala-string-vs-java-lang-string-type-in​​ference –

回答

11

首先,「以及它甚至不是java.lang.String中」說法是不完全正確的。平原String名字來自於Predef對象定義的類型別名:

type String = java.lang.String 

Predef內部在每Scala的消息,因此你使用String,而不是完全java.lang.String,但實際上它們是相同的。

java.lang.String是JVM在特殊的方式處理非常特殊的類。正如@ pagoda_5b說,它被聲明爲final,這是不可能將其擴展(這其實不錯),所以Scala庫提供了一個包裝(RichString)與額外的操作,並提供默認的隱式轉換String -> RichString

但是,稍有不同的情況與IntegerCharacterBoolean等你看,即使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運行時)的原語的優雅方法。

4

我只是猜測這裏

如果你看的文檔,你可以看到,原語的斯卡拉版本給大家的預期運營商,關於數字類型,或布爾類型,並且明智的轉換工作,而不是訴諸拳擊拆箱,因爲java.lang包裝。

我認爲這個選擇是爲了給予基本類型所期望的統一和自然的訪問,同時使它們與其他任何scala類型一樣。

我想這java.lang.String需要一種不同的方法,是在其實施的Object已經和final。所以「最少痛苦的路徑」是在它周圍創建一個隱含的Rich包裝來獲取對String的缺失操作,同時保持其餘的不變。

要看到它的另一種方式,java.lang.String已經足夠好,是,是不可改變的,什麼-人。

值得一提的是,其他的「原始」類型Scala中有提供額外的明智的業務自身豐富的包裝。

相關問題