首页 文章

Scala:抽象类型模式A未被选中,因为它被擦除消除了

提问于
浏览
14

我正在编写可以捕获特定类型的异常的函数 .

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 回答

  • 19

    您可以在this answer中使用 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) =>
      }
    }
    

    另请注意,一般情况下,您应该使用 Tryrecover 方法: 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]`
    }
    
  • 2

    对于每种类型检查(例如 case a: A ),JVM需要相应的 class 对象来执行检查 . 在您的情况下,JVM没有类对象,因为 A 是一个变量类型参数 . 但是,您可以通过隐式将 Manifest[A] 传递给 myFunc 来获取有关 A 的其他信息 . 作为简写,您只需将 : Manifest 添加到 A 的类型声明中:

    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
        }
    }
    

相关问题