Scala中的类型擦除在Option匹配时的应用

9 浏览
0 Comments

Scala中的类型擦除在Option匹配时的应用

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 帖子,但我不理解这里的类型擦除。

admin 更改状态以发布 2023年5月23日
0
0 Comments

这是在警告您,无法在运行时确定值是否为Some[Test],而不是Some[Int]Some[其他任何类型]。这是由于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]匹配,但还为您提供封装的值,以便您可以直接在案例块内使用。

如果确实需要确保值为Test类型,则可以尝试理解TypeTags(例如,您提到的链接或参见此处),或者您可以采用有些恶心的isInstanceOf方法:

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

编辑:或者

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

如@senia的回答所述。

0
0 Comments

在运行时,jvm中没有Some[Test]Some[String],只有Some[Any]。因此,您无法匹配Some[Test]。在这种情况下,您可以像这样匹配Some的内容:

case Some(e: Test) => println(s"$e matched")

0