我知道什么类型的擦除是。所以,我认为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和常规编译 - >运行循环中的工作方式相同。