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]Some 的一个而不是任何其他子类型。就您而言,这似乎无关紧要,因此我不会发出警告。

另一方面,更惯用(和实用!)将是以下内容:

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]. 所以你不能匹配 on Some[Test]

在这种情况下,您可以匹配Some如下内容:

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