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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21180973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 06:00:11  来源:igfitidea点击:

Scala: abstract type pattern A is unchecked since it is eliminated by erasure

scalagenericsfunctional-programmingtype-erasurescala-template

提问by tmporaries

I am writing the function that can catch exceptions of the certain type only.

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

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

What is the corrent way to bypass jvm type erasure in such case?

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

回答by senia

You could use ClassTaglike in this answer.

你可以ClassTag这个答案中使用like 。

But I'd prefer this approach:

但我更喜欢这种方法:

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

Usage:

用法:

myFunc{ case _: MyException => }

Using ClassTag:

使用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) =>
  }
}

Note also that in general you should use Trywith recovermethod: Trywill catch only NonFatalexceptions.

另请注意,通常您应该使用Trywith recovermethod: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]`
}

回答by Stefan Endrullis

For every type check (e.g. case a: A) the JVM needs the corresponding classobject to perform the check. In your case the JVM does not have the class object, because Ais a variable type parameter. However, you can add additional information about Aby implicitly passing a Manifest[A]to myFunc. As a shorthand you can just add : Manifestto your type declaration of A:

对于每个类型检查(例如case a: A),JVM 需要相应的class对象来执行检查。在您的情况下,JVM 没有类对象,因为A它是变量类型参数。但是,您可以A通过隐式传递 aManifest[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
    }
}