Exception 我可以避免在使用catching(…)时多余地抛出一个可丢弃的对象吗?

Exception 我可以避免在使用catching(…)时多余地抛出一个可丢弃的对象吗?,exception,scala,Exception,Scala,我正在使用util.control.Exception.catching将内部异常转换为特定于我的库的异常类型: import util.control.Exception._ abstract class MyException extends Exception case class ErrorOccurredDuringFoo(e : Exception) extends MyException def foo : Foo = { catching(classOf[Excep

我正在使用
util.control.Exception.catching
将内部异常转换为特定于我的库的异常类型:

import util.control.Exception._

abstract class MyException extends Exception

case class ErrorOccurredDuringFoo(e : Exception) extends MyException

def foo : Foo = {
    catching(classOf[Exception]) either { fooInternals } match {
        case Left(e) => throw ErrorOccurredDuringFoo(e)
        case Right(v) => v
    }
}
不幸的是,这不起作用。应用由
other
返回的
Catch
不会返回
other[Exception,Foo]
,而是返回
other[Throwable,Foo]
。但是我已经告诉过
捕获
我希望它只捕获
异常
的子类型,而不是所有的
可丢弃的
,并且在内部它已经匹配了一个
异常


我用得对吗?我是否无法说服
catching
将它捕获的异常作为我要求它捕获的异常类的实例返回?我最好只添加一个冗余的
作为[Exception]
的实例?如果可以避免的话,我不希望这样做,因为
catching
实例在逻辑上可以在其他地方创建,如果有一天我将其更改为
catching[Throwable]
而不更改
erroroccurrendduringfoo
,我希望得到一个编译错误,当转换为
异常失败时,不是运行时错误。

Catch
未在
Throwable
上参数化,仅在结果类型上参数化。向下播放可丢弃类型的唯一方法是使用mkCatcher方法:

val c = catching[Foo](
  mkCatcher(
    (t: Throwable) => t.getClass == classOf[MyException],
    (e: MyException) => throw new ErrorOccurredDuringFoo(e)))
c(fooInternals)
但是,
Catch
使用了一个
Catcher[T]
——它实际上只是
部分函数[Throwable,T]
的别名

由于case语句是一个
部分函数
,我们可以使用模式匹配:

val c: Catcher[Foo] = {
  case e: MyException => throw new ErrorOccurredDuringFoo(e)
}
catching(c)(fooInternals)

你可以这样写:

def foo : Foo = {
    catching(classOf[Exception]) either { fooInternals } match {
        case Left(e: Exception) => throw ErrorOccurredDuringFoo(e)
        case Right(v) => v
    }
}

有趣的是,它没有抱怨丢失的案例。

谢谢!结果好多了,真有趣。假设它最终相当于运行时向下转换,如果
classOf[Exception]
更改为
classOf[Throwable]
,编译器将不会静态地知道
case Left(e:Exception)
是错误的,结果将是运行时匹配错误。