2014-01-19 32 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和常规编译 - >运行循环中的工作方式相同。