Scala:抽象类型模式A是未选中的,因为它是通过擦除消除的

Scala:抽象类型模式A是未选中的,因为它是通过擦除消除的,scala,generics,functional-programming,type-erasure,scala-template,Scala,Generics,Functional Programming,Type Erasure,Scala Template,我编写的函数只能捕获特定类型的异常 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 } } def my

我编写的函数只能捕获特定类型的异常

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
    }
}
def myFunc[A//警告:抽象类型模式A未选中,因为它已通过擦除消除
}
}

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

您可以像中一样使用
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) =>
  }
}
对于每个类型检查(例如,
case a:a
),JVM都需要相应的
class
对象来执行检查。在您的情况下,JVM没有class对象,因为
a
是一个变量类型参数。但是,您可以通过隐式传递
Manifest[a]来添加有关
a
的附加信息
myFunc
。作为简写,您可以将
: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
    }
}
def myFunc[A//警告:抽象类型模式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
    }
}