tmp*_*ies 16 generics functional-programming scala 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
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下绕过jvm类型擦除的正确方法是什么?
sen*_*nia 23
你可以ClassTag
在这个答案中使用.
但我更喜欢这种方法:
def myFunc(recover: PartialFunction[Throwable, Unit]): Unit = {
try {
println("Hello world") // or something else
} catch {
recover
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
myFunc{ case _: MyException => }
Run Code Online (Sandbox Code Playgroud)
使用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) =>
}
}
Run Code Online (Sandbox Code Playgroud)
另请注意,通常您应该使用Try
with recover
method: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]`
}
Run Code Online (Sandbox Code Playgroud)
对于每种类型检查(例如case a: A
),JVM需要相应的class
对象来执行检查。在您的情况下,JVM没有类对象,因为A
它是变量类型参数。但是,您可以A
通过将隐式传递给Manifest[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
}
}
Run Code Online (Sandbox Code Playgroud)