看看这个Scala类:
class Example {
val (x, y): (Int, Int) = (1, 2)
}
对此进行编译会产生警告:
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)
^
删除显式类型注释会消除此警告:
class Example {
val (x, y) = (1, 2)
}
为什么我会收到警告,为什么删除显式类型注释会删除它?至于我没有看到任何真正的变化,x
和y
仍然是类型Int
而没有类型注释。
答案 0 :(得分:13)
您可以将示例重写为:
class Example {
val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}
此模式匹配实际上包含2个匹配项 - 现在说:采用Tuple2[Int, Int]
类型的右侧对象,并在unapply[Int, Int]
随播广告对象上调用方法Tuple2
。然后,unapply[Int, Int]
将验证对象是否确实具有Tuple2
类型,并且其结果值将用于将值绑定到变量x
和y
。
之后,此模式匹配包含: Tuple2[Int, Int]
,因此它会尝试动态执行isInstanceOf[Tuple2[Int, Int]]
检查,以查看该对象是否还具有类型Tuple2[Int, Int]
。但是,泛型类型信息在运行时被擦除,因此编译器警告它无法实际生成验证对象是否为类型参数[Int, Int]
实例化的代码。
以同样的方式,在以下模式匹配中:
val a: AnyRef = (1, 2)
a match {
case t2: Tuple[Int, Int] =>
}
你会收到类似的警告。
答案 1 :(得分:5)
我认为你问题的简短回答是:
class Example {
val (x: Int, y: Int) = (1, 2)
}
因为(Int, Int)
不是类型,而(x: Int, y: Int)
是有效的模式表达式。