关于此 Scala 模式匹配中未经检查的类型参数的警告? [英] Warning about an unchecked type argument in this Scala pattern match?

查看:49
本文介绍了关于此 Scala 模式匹配中未经检查的类型参数的警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个文件:

object Test extends App {
    val obj = List(1,2,3) : Object
    val res = obj match {
       case Seq(1,2,3) => "first"
       case _ => "other"
    }
    println(res)
}

发出此警告:

Test.scala:6: warning: non variable type-argument A in type pattern Seq[A]  
is unchecked since it is eliminated by erasure
   case Seq(1,2,3) => "first"

Scala 版本 2.9.0.1.

Scala version 2.9.0.1.

我不知道如何需要擦除的类型参数来执行匹配.第一个 case 子句旨在询问 obj 是否是一个 Seq,其中 3 个元素等于 1、2 和 3.

I don't see how an erased type parameter is needed to perform the match. That first case clause is meant to ask if obj is a Seq with 3 elements equal to 1, 2, and 3.

如果我写了以下内容,我会理解这个警告:

I would understand this warning if I had written something like:

case strings : Seq[String] => ...

为什么我会收到警告,有什么好的方法可以让它消失?

Why do I get the warning, and what is a good way to make it go away?

顺便说一下,我确实想匹配静态类型的对象.在实际代码中,我正在解析类似 Lisp 数据的内容 - 它可能是字符串、数据序列、符号、数字等.

By the way, I do want to match against something with static type of Object. In the real code I'm parsing something like a Lisp datum - it might be an String, sequence of datums, Symbol, Number, etc.

推荐答案

以下是对幕后发生的事情的一些见解.考虑以下代码:

Here is some insight to what happens behind the scene. Consider this code:

class Test {
  new Object match { case x: Seq[Int] => true }
  new Object match { case Seq(1) => true }
}

如果您使用 scalac -Xprint:12 -unchecked 进行编译,您将在擦除阶段 (id 13) 之前看到代码.对于第一个类型模式,您将看到如下内容:

If you compile with scalac -Xprint:12 -unchecked, you'll see the code just before the erasure phase (id 13). For the first type pattern, you will see something like:

<synthetic> val temp1: java.lang.Object = new java.lang.Object();
if (temp1.isInstanceOf[Seq[Int]]()) 

对于Seq 提取器模式,您将看到如下内容:

For the Seq extractor pattern, you will see something like:

<synthetic> val temp3: java.lang.Object = new java.lang.Object();
if (temp3.isInstanceOf[Seq[A]]()) {
  <synthetic> val temp4: Seq[A] = temp3.asInstanceOf[Seq[A]]();
  <synthetic> val temp5: Some[Seq[A]] = collection.this.Seq.unapplySeq[A](temp4);
  // ...
}

在这两种情况下,都有一个类型测试来查看对象是否属于 Seq 类型(Seq[Int]Seq[A]).在擦除阶段将消除类型参数.因此警告.尽管第二个可能是意外的,但检查类型确实有意义,因为如果对象不是 Seq 类型,该子句将不匹配,JVM 可以继续执行下一个子句.如果类型匹配,则可以将对象强制转换为 Seq 并且可以调用 unapplySeq.

In both cases, there is a type test to see if the object is of type Seq (Seq[Int] and Seq[A]). Type parameters will be eliminated during the erasure phase. Thus the warning. Even though the second may be unexpected, it does make sense to check the type since if object is not of type Seq that clause won't match and the JVM can proceed to the next clause. If the type does match, then the object can be casted to Seq and unapplySeq can be called.

RE:关于类型检查的 thoredge 评论.可能我们在谈论不同的事情.我只是说:

RE: thoredge comment on the type check. May be we are talking about different things. I was merely saying that:

(o: Object) match {
  case Seq(i) => println("seq " + i)
  case Array(i) => println("array " + i)
}

翻译成类似:

if (o.isInstanceOf[Seq[_]]) { // type check
  val temp1 = o.asInstanceOf[Seq[_]] // cast
  // verify that temp1 is of length 1 and println("seq " + temp1(0))
} else if (o.isInstanceOf[Array[_]]) { // type check
  val temp1 = o.asInstanceOf[Array[_]] // cast
  // verify that temp1 is of length 1 and println("array " + temp1(0))
}

使用类型检查,以便在转换完成时不会出现类转换异常.

The type check is used so that when the cast is done there is no class cast exception.

类型模式Seq[A]中的警告非变量类型参数A由于被擦除消除而未被检查是否合理,是否会出现类转换异常的情况即使是类型检查,我也不知道.

Whether the warning non variable type-argument A in type pattern Seq[A] is unchecked since it is eliminated by erasure is justified and whether there would be cases where there could be class cast exception even with the type check, I don't know.

这是一个例子:

object SeqSumIs10 {
  def unapply(seq: Seq[Int]) = if (seq.sum == 10) Some(seq) else None
}

(Seq("a"): Object) match {
  case SeqSumIs10(seq) => println("seq.sum is 10 " + seq) 
}
// ClassCastException: java.lang.String cannot be cast to java.lang.Integer

这篇关于关于此 Scala 模式匹配中未经检查的类型参数的警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆