[英]Warning about an unchecked type argument in this Scala pattern match?
這個文件:
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。
我沒有看到如何執行匹配需要擦除類型參數。 第一個案例子句是為了詢問obj是否是一個3個元素等於1,2和3的Seq。
如果我寫了類似的東西,我會理解這個警告:
case strings : Seq[String] => ...
為什么我會收到警告,什么是讓它消失的好方法?
順便說一句,我確實希望與靜態類型的Object匹配。 在實際代碼中,我正在解析類似於Lisp基准的東西 - 它可能是一個字符串,基准序列,符號,數字等。
以下是對場景背后發生的事情的一些見解。 考慮以下代碼:
class Test {
new Object match { case x: Seq[Int] => true }
new Object match { case Seq(1) => true }
}
如果使用scalac -Xprint:12 -unchecked
編譯, 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
可以調用unapplySeq
。
RE:thoredge評論類型檢查。 可能我們正在談論不同的事情。 我只是說:
(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))
}
使用類型檢查,以便在完成轉換時沒有類轉換異常。
類型模式Seq [A]中的警告非變量類型參數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)
}
// ClassCastException: java.lang.String cannot be cast to java.lang.Integer
在外面聲明匹配對象至少會讓它消失,但我不確定為什么:
class App
object Test extends App {
val obj = List(1,2,3) : Object
val MatchMe = Seq(1,2,3)
val res = obj match {
case MatchMe => "first"
case _ => "other"
}
println(res)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.