"通过擦除消除" Scala中的警告

时间:2014-08-24 17:19:35

标签: scala tuples

我有一个代码检查四元组输入如下:

if (v.isInstanceOf[(Int, Int, Int, Int)]) {
  val value = v.asInstanceOf[(Int, Int, Int, Int)]

我从Scala编译器收到警告eliminated by erasure

8: non-variable type argument Int in type (Int, Int, Int, Int) is unchecked since it is 
eliminated by erasure
[warn]     if (v.isInstanceOf[(Int, Int, Int, Int)]) {

这是为了什么,以及如何更改代码以删除警告?

1 个答案:

答案 0 :(得分:2)

在JVM上,类文件字节代码中的类型参数或“泛型”被“擦除”。仅保留基本类型。例如,如果你有

val v: Tuple4[Int, Int, Int, Int] = (1, 2, 3, 4)

然后,此类型只能在运行时标识为

Tuple4[_, _, _, _]

在大多数情况下,这并不重要,因为您的类型检查在编译期间发生,因此信息仍然存在。但是如果你在运行时有一个值,并且你在运行时测试它是Tuple4的实例,那么元组的元素类型是未知的。

换句话说,无论值是否为整数,任何 if的{​​{1}}子句都为true。尝试使用Tuple4进行测试,它将“匹配”:

("a", 'b', 3.4, true)

好处是 - 如果你在运行时有,那么你可以只测试单个元组元素:

def test1(v: Any): Option[(Int, Int, Int, Int)] = 
  if (v.isInstanceOf[(Int, Int, Int, Int)]) 
    Some(v.asInstanceOf[(Int, Int, Int, Int)])
  else
    None

test1((1, 2, 3, 4)).map(_._1)  // Some 1
test1(("a", 'b', 3.4, true)).map(_._1)  // runtime error!