簡體   English   中英

關於此Scala模式匹配中未經檢查的類型參數的警告?

[英]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可以繼續執行下一個子句。 如果類型匹配,則可以將對象轉換為SequnapplySeq可以調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM