2014-11-03 71 views
1

我很好奇,爲什麼scala.util.Try有異常的類型像爲什麼Scala的Try沒有異常類型的類型參數?

abstract class Try[+E <: Throwable, +T] { 
    recoverWith[U >: T](f: PartialFunction[E, Try[E, U]]): Try[E, U] 
    ... 
} 

沒有類型參數會和文檔幫助,如

仍然無法表達不相交的異常類型,如throws SecurityException, IllegalArgumentException ,但在這個方向至少有一步。

+0

您的目標是讓'Try {foo}'只捕獲'foo'中的特定異常而不是所有異常? – 2014-11-03 22:17:21

+0

我的目標是要表明返回Try的函數只能通過特定的異常失敗,而不能通過任何Throwable – eprst 2014-11-03 22:22:20

+0

我的回答在任何方面都是相關的嗎? – 2014-11-10 11:58:43

回答

1

這可能是你在找什麼:

import scala.util.control.Exception._ 
import scala.util.{ Success, Failure } 

def foo(x: Int): Int = x match { 
    case 0 => 3 
    case 1 => throw new NumberFormatException 
    case _ => throw new NullPointerException 
} 

val Success(3) = catching(classOf[NumberFormatException]).withTry(foo(0)) 
val Failure(_: NumberFormatException) = catching(classOf[NumberFormatException]).withTry(foo(1)) 
// val neverReturns = catching(classOf[NumberFormatException]).withTry(foo(2)) 

scala.util.control.Exception$


但是,沒有辦法專門Try[T]喜歡的東西假想Try[ExcType, T];爲了使這種工作,你需要像Either(但可能是一些更復雜,如scalaz.\/,或超過1的異常類,無形Coproduct):

def bar(x: Int): Either[NumberFormatException, Int] = { 
    catching(classOf[NumberFormatException]).withTry(foo(x)) match { 
    case Success(x) => Right(x) 
    case Failure(exc) => Left(exc.asInstanceOf[NumberFormatException]) 
    } 
} 

println(bar(0)) // Right(3) 
println(bar(1)) // Left(java.lang.NumberFormatException) 
// println(bar(2)) // throws NullPointerException 

它應該是可以將其推廣到可與任意數量的異常類型一起使用的通用幫助器中。在這種情況下,你一定要與Shapeless'Coproductfacilities for abstracting over arity一起工作。不幸的是,這是一個不平凡的練習,我現在沒有時間爲你實施。

相關問題