为什么将成员变量的擦除警告声明为元组?

Jes*_*per 9 scala compiler-warnings type-erasure

看看这个Scala类:

class Example {
  val (x, y): (Int, Int) = (1, 2)
}
Run Code Online (Sandbox Code Playgroud)

编译这会导致警告:

Example.scala:2: warning: non variable type-argument Int in type pattern
               (Int, Int) is unchecked since it is eliminated by erasure
    val (x, y): (Int, Int) = (1, 2)
                ^
Run Code Online (Sandbox Code Playgroud)

删除显式类型注释会消除此警告:

class Example {
  val (x, y) = (1, 2)
}
Run Code Online (Sandbox Code Playgroud)

为什么我会收到警告,为什么删除显式类型注释会删除它?据我所知,没有任何真正的变化,x并且y仍然是Int没有类型注释的类型.

axe*_*l22 13

您可以将示例重写为:

class Example {
  val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}
Run Code Online (Sandbox Code Playgroud)

这种模式匹配实际上包含2个匹配 - 它现在说:采取类型的右侧对象Tuple2[Int, Int]并调用伴随对象unapply[Int, Int]上的方法Tuple2.在unapply[Int, Int]然后将验证对象确实具有类型Tuple2,并将其结果值将被用来值绑定到变量xy.

之后,此模式匹配包含: Tuple2[Int, Int],因此它会尝试isInstanceOf[Tuple2[Int, Int]]动态检查以查看该对象是否还具有该类型Tuple2[Int, Int].但是,泛型类型信息在运行时被擦除,因此编译器警告它不能实际生成验证对象是否为类型参数实例化的代码[Int, Int].

以同样的方式,在以下模式匹配中:

val a: AnyRef = (1, 2)
a match {
  case t2: Tuple[Int, Int] => 
}
Run Code Online (Sandbox Code Playgroud)

你会收到类似的警告.


Mar*_*cio 5

我想你问题的简短回答是:

class Example {
  val (x: Int, y: Int) = (1, 2)
}
Run Code Online (Sandbox Code Playgroud)

因为(Int, Int)不是一个类型,(x: Int, y: Int)而是一个有效的模式表达式.