我有一个只在输入是四个整数的元组时计算元组值的函数。
def add(v:Any) = {
if (v.isInstanceOf[(Int, Int, Int, Int)]) {
val v2 = v.asInstanceOf[(Int, Int, Int, Int)]
println(v2._1 + v2._2 + v2._3 + v2._4)
} else {
println("NOP")
}
}
object Main extends App {
add((1,1,1,1))
add((1,2))
}
Main.main(args)
它正在工作,但我收到一条警告“非变量类型参数......未被检查”警告。
warning: non-variable type argument Int in type (Int, Int, Int, Int) is
unchecked since it is eliminated by erasure
if (v.isInstanceOf[(Int, Int, Int, Int)]) {
为什么会出现此错误,以及删除此警告消息的最佳方法是什么?
答案 0 :(得分:1)
这是由type erasure
在编译时引起的,您可以通过TypeTag解决它:
import scala.reflect.runtime.universe._
def add[T](v:T)(implicit t: TypeTag[T]) = {
if ( t.tpe =:= typeOf[(Int, Int, Int, Int)]) {
val v2 = v.asInstanceOf[(Int, Int, Int, Int)]
println(v2._1 + v2._2 + v2._3 + v2._4)
} else {
println("NOP")
}
}
答案 1 :(得分:1)
您可以使用模式匹配替换instanceOf
,并使用@unchecked
def add(v: Any) = v match {
case t: (Int, Int, Int, Int) @unchecked =>
println(t._1 + t._2 + t._3 + t._4)
case _ =>
println("NOP")
}
如果您传递的Tuple4
不是(Int, Int, Int, Int)
,您将获得ClassCastException
错误清楚地表明,由于类型擦除,将删除泛型类型的元组,因此编译器无法确保这将在运行时工作,它只会看到Tuple4
是否通过,而不是它是什么包含。
我提出的解决方案如果可能使用(Int, Int, Int, Int)
Tuple4
之外的其他函数调用该函数会导致您遇到麻烦,然后您应继续使用TypeTag
s,除此之外只是看起来更干净,不需要反思。
答案 2 :(得分:1)
如果你确实需要检查参数是否是四个Int
的元组,那么正确的方法是检查每个组件:
def add(v: Any) = v match {
case (i1: Int, i2: Int, i3: Int, i4: Int) =>
println(i1 + i2 + i3 + i4)
case _ =>
println("NOP")
}