我知道什麼類型的擦除是。所以,我認爲scala REPL無法準確檢測泛型類型。
正如我如上所述,階不能檢測圖案通用類型的匹配是這樣的:
泛型如何在Scala REPL中工作?
case list: List[Int]
但是,當我聲明列表類型值,階檢測什麼一般類型被包含。
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)
這怎麼可能?
我知道什麼類型的擦除是。所以,我認爲scala REPL無法準確檢測泛型類型。
正如我如上所述,階不能檢測圖案通用類型的匹配是這樣的:
泛型如何在Scala REPL中工作?
case list: List[Int]
但是,當我聲明列表類型值,階檢測什麼一般類型被包含。
scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 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中鍵入一些代碼時,它首先被編譯成字節碼,然後進行評估。顯示的類型信息來自編譯階段,所以它不會遭受類型擦除。
當你寫:
val a = List(1,2,3)
Scala的使用類型推斷找到在編譯時最匹配的類型。本質上,它會改寫你作爲:
val a: List[Int] = ...
它將使用編譯時這個參數類型信息輸入檢查你的代碼,並刪除它之後,所以你會得到你的程序List[_]
。這是因爲JVM以這種方式工作 - 類型擦除。
當您在運行時在列表中匹配模式時,它的類型信息將被刪除,因此任何List
都將匹配。 Scala編譯器會在編譯期間警告你。
這在REPL和常規編譯 - >運行循環中的工作方式相同。