2014-01-19 30 views
0

我知道什麼類型的擦除是。所以,我認爲scala REPL無法準確檢測泛型類型。
正如我如上所述,階不能檢測圖案通用類型的匹配是這樣的:
泛型如何在Scala REPL中工作?

case list: List[Int] 

但是,當我聲明列表類型值,階檢測什麼一般類型被包含。

scala> val a = List(1,2,3) 
    a: List[Int] = List(1, 2, 3) 

這怎麼可能?

回答

3
val a = List(1,2,3) 

這相當於:

val a = List.apply[Int](1,2,3) 

List.apply[Int](...)結果類型是List[Int],因此,型inferencer分配此類型標識符a。這發生在彙編。 REPL在運行時不會「檢測」類型。

這是一個模式匹配不同:

val a: Any = ... 
a match { 
    case list: List[Int] => ... 
} 

在這裏,我們有一個價值a,對此我們沒有任何類型的信息。所以我們試圖檢查它是什麼類型,但現在我們在運行時中這樣做。在這裏,我們確實無法確定確切的類型。我們能做的最好的是匹配List[_]

總結: 當你在REPL中鍵入一些代碼時,它首先被編譯成字節碼,然後進行評估。顯示的類型信息來自編譯階段,所以它不會遭受類型擦除。

1

當你寫:

val a = List(1,2,3) 

Scala的使用類型推斷找到在編譯時最匹配的類型。本質上,它會改寫你作爲:

val a: List[Int] = ... 

它將使用編譯時這個參數類型信息輸入檢查你的代碼,並刪除它之後,所以你會得到你的程序List[_]。這是因爲JVM以這種方式工作 - 類型擦除。

當您在運行時在列表中匹配模式時,它的類型信息將被刪除,因此任何List都將匹配。 Scala編譯器會在編譯期間警告你。

這在REPL和常規編譯 - >運行循環中的工作方式相同。