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

Posted

技术标签:

【中文标题】Scala:抽象类型模式 A 未选中,因为它已被擦除消除【英文标题】:Scala: abstract type pattern A is unchecked since it is eliminated by erasure 【发布时间】:2014-01-17 08:18:06 【问题描述】:

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

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 类型擦除的正确方法是什么?

【问题讨论】:

【参考方案1】:

你可以像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
    

【讨论】:

以上是关于Scala:抽象类型模式 A 未选中,因为它已被擦除消除的主要内容,如果未能解决你的问题,请参考以下文章

Spring RMI 的替代方案是啥? (因为它已被弃用)

Java泛型之类型未被擦除

错误“此消息无法支持该操作,因为它已被读取”

UnexpectedRollbackException:事务回滚,因为它已被标记为仅回滚

如何启用 HSQLDB 管理器工具菜单,因为它已被禁用

实现共享位置地点选择器,与没有地点选择器的 WhatsApp 相同,因为它已被弃用