使用Scala删除警告消息“类型中的on-variable类型参数Int ...未选中”

时间:2016-03-26 06:24:57

标签: scala function warnings

我有一个只在输入是四个整数的元组时计算元组值的函数。

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)]) {

为什么会出现此错误,以及删除此警告消息的最佳方法是什么?

3 个答案:

答案 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")
}