5
object Test {
  def main(args: Array[String]) {
    val list: List[Double] = List(1.0, 2.0, 3.0, 4.0)
    val none = None

    case class Test()

    val test = Test()

    def f(x: Any) = x match {
        case _: Some[Test] => println("_ matched")
        case None => println("None matched")
    }

    f(list)
    f(none)
    f(test)
  }
}

上記のコードをコンパイルしようとすると、「消去による消去」というコンパイル時の警告が表示されます。

   $>scalac Test.scala
    Test.scala:11: warning: non-variable type argument Test in type pattern
 Some[Test] is unchecked since it is eliminated by erasure
            case _: Some[Test] => println("_ matched")
                    ^
    one warning found

この高く評価されている Stackoverflowの投稿を読みましたが、ここで型消去が理解できません。

4

2 に答える 2

9

Some[Test]これは、実行時に値が、Some[Int]またはであるかどうかを判断する方法がないことを警告していますSome[anything else]。これは、JVM が型パラメーターを認識していないためです (つまり、Java で型消去があるのと同じ理由です)。あなたが参照する投稿は、このタイプの消去の問題を回避するために Scala で提供される方法を示していますSome[Test]。あなたの場合、それは関連していないように見えるので、私は警告を気にしません。

一方、より慣用的な (そして実用的な!) 表現は次のようになります。

def f(x: Any) = x match {
    case Some(y) => println(s"x matched to Some - wrapped value is $y")
    case None => println("None matched")
}

これは に一致しSome[Any]ますが、case ブロック内で直接使用できるラップされた値も提供します。

値が Test 型であることを確認する必要がある場合は、TypeTags (言及したリンク、またはここを参照) に頭を包むか、やや厄介な isInstanceOf メソッドに頼ることができます。

case Some(y) if (y.isInstanceOf[Test]) => ...

編集者

case Some(e: Test) => ...

@seniaの回答によると。

于 2013-09-04T02:56:44.183 に答える
9

実行時にが存在しjvmないSome[Test]か、Some[String]存在するだけSome[Any]です。したがって、 で一致することはできませんSome[Test]

この場合、次のSomeような内容で照合できます。

case Some(e: Test) => println(s"$e matched")
于 2013-09-04T02:56:52.713 に答える