删除警告消息";关于类型中的变量类型参数Int。。。“未经检查”;用Scala

删除警告消息";关于类型中的变量类型参数Int。。。“未经检查”;用Scala,scala,function,warnings,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 Mai

我有一个函数,仅当输入是四个整数的元组时才计算元组值

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

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

这是由编译时的
类型擦除引起的,您可以通过以下方法解决此问题:


这是由编译时的
类型擦除造成的,您可以通过以下方法解决:


您可以使用模式匹配替换
instanceOf
s,并使用
@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")
}
如果您传递一个不是
(Int,Int,Int,Int,Int)
元组4
,您将得到一个
ClassCastException

错误明确指出,由于类型擦除,元组的泛型类型将被删除,因此编译器无法确保这在运行时正常工作,它将只查看是否传递了
Tuple4
,而不是它包含的内容


我提出的解决方案会给您带来麻烦,如果可能会使用
(Int,Int,Int,Int)
Tuple4
,然后您应该继续使用
TypeTag
s,另外,它看起来更干净,不需要反射。

您可以用模式匹配替换
实例,并用
@未选中的
来抑制警告

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")
}
如果您传递一个不是
(Int,Int,Int,Int,Int)
元组4
,您将得到一个
ClassCastException

错误明确指出,由于类型擦除,元组的泛型类型将被删除,因此编译器无法确保这在运行时正常工作,它将只查看是否传递了
Tuple4
,而不是它包含的内容


我提出的解决方案会给您带来麻烦,如果可能会使用
(Int,Int,Int,Int)
Tuple4
,然后您应该继续使用
TypeTag
s,在其他方面,它看起来非常干净,不需要反射。

如果您确实需要检查参数是否是四个
Int
s的元组,正确的方法是检查每个组件:

def add(v: Any) = v match {
  case (i1: Int, i2: Int, i3: Int, i4: Int) =>
    println(i1 + i2 + i3 + i4)
  case _ =>
    println("NOP")
}

如果您确实需要检查参数是否为四个
Int
s的元组,正确的方法是检查每个组件:

def add(v: Any) = v match {
  case (i1: Int, i2: Int, i3: Int, i4: Int) =>
    println(i1 + i2 + i3 + i4)
  case _ =>
    println("NOP")
}

IMO这是一个更好的选择,因为它更干净、更惯用。IMO这是一个更好的选择,因为它更干净、更惯用。这实际上没有所需的行为,它只在参数的静态类型为
(Int,Int,Int,Int)
时才起作用。例如,如果调用返回
Any
的函数的返回值,它将不起作用。这实际上没有所需的行为,它只在参数的静态类型为
(Int,Int,Int,Int)
时起作用。例如,如果对返回
Any
的函数的返回值进行调用,它将不起作用。