Scala:抽象类型模式 A 未经检查,因为它被擦除消除了。

28
我正在编写一个函数,可以仅捕获特定类型的异常。
def myFunc[A <: Exception]() {
    try {
        println("Hello world") // or something else
    } catch {
        case a: A => // warning: abstract type pattern A is unchecked since it is eliminated by erasure
    }
}

在这种情况下,绕过JVM类型擦除的正确方法是什么?

2个回答

31

你可以像这个答案中所示,使用ClassTag

但我更喜欢这种方法:

def myFunc(recover: PartialFunction[Throwable, Unit]): Unit = {
  try {
    println("Hello world") // or something else
  } catch {
    recover
  }
}

使用方法:

myFunc{ case _: MyException => }

使用ClassTag

import scala.reflect.{ClassTag, classTag}

def myFunc[A <: Exception: ClassTag](): Unit = {
  try {
    println("Hello world") // or something else
  } catch {
    case a if classTag[A].runtimeClass.isInstance(a) =>
  }
}

注意通常情况下,你应该使用recover方法与Try一起使用:Try只会捕获NonFatal异常。

def myFunc(recover: PartialFunction[Throwable, Unit]) = {
  Try {
    println("Hello world") // or something else
  } recover {
    recover
  }.get // you could drop .get here to return `Try[Unit]`
}

9
对于每个类型检查(例如case a: A),JVM需要相应的class对象来执行检查。在您的情况下,JVM没有类对象,因为A是一个变量类型参数。但是,您可以通过隐式传递Manifest[A]myFunc来添加有关A的其他信息。作为一种简写,您可以在A的类型声明中添加: Manifest
def myFunc[A <: Exception : Manifest]() {
    try {
        println("Hello world") // or something else
    } catch {
        case a: A => // warning: abstract type pattern A is unchecked since it is eliminated by erasure
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接