以下是幕后发生的一些情况。请考虑以下代码:
class Test {
new Object match { case x: Seq[Int] => true }
new Object match { case Seq(1) => true }
}
如果你使用
scalac -Xprint:12 -unchecked
进行编译,你会看到在类型擦除阶段之前(id 13)的代码。对于第一个
类型模式,你会看到类似以下内容:
<synthetic> val temp1: java.lang.Object = new java.lang.Object();
if (temp1.isInstanceOf[Seq[Int]]())
对于“Seq提取器模式”,您将看到类似以下内容的东西:
<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
函数。
关于thoredge对类型检查的评论,也许我们正在谈论不同的事情。我只是在说:
(o: Object) match {
case Seq(i) => println("seq " + i)
case Array(i) => println("array " + i)
}
翻译成中文大概是这样:
if (o.isInstanceOf[Seq[_]]) {
val temp1 = o.asInstanceOf[Seq[_]]
} else if (o.isInstanceOf[Array[_]]) {
val temp1 = o.asInstanceOf[Array[_]]
}
类型检查用于确保在执行转换操作时不会出现类转换异常。
关于警告“非变量类型参数A在类型模式Seq[A]中未经检查,因为它会被擦除”是否合理,以及在进行类型检查的情况下是否仍可能出现类转换异常,我不清楚。
编辑:这里是一个示例:
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)
}