I've recently seen code like this:
val maybeInt = catching(classOf[NFE]) opt arg.toInt
What is this opt? An Option? Why isn't it using getOrElse to extract the valu开发者_JS百科e? In the above code, will maybeInt be None if a NumberFormatException gets thrown?
catching looks like it's some sort of method call, doesn't it? It is, but it actually returns an instance of a class Catch; it doesn't directly take an argument. This class has two methods that are particularly useful for dealing with exceptions (and several more for catching multiple exceptions). The first is
def opt [U >: T] (body: ⇒ U) : Option[U]
which is being used here--you give it something that may throw an exception, and it will return Some(result) if everything went okay, and None if the targeted exception was caught:
scala> type NFE = NumberFormatException
defined type alias NFE
scala> import scala.util.control.Exception._
import scala.util.control.Exception._
scala> catching(classOf[NFE]).opt( "fish".toInt )
res0: Option[Int] = None
scala> catching(classOf[NFE]).opt( "42".toInt )
res1: Option[Int] = Some(42)
You can then deal with this with map or filter or getOrElse or whatever else you use to deal with options.
The other useful method is either, which returns an instance of Left(exception) if an exception was thrown, and a Right(result) if it was not:
scala> catching(classOf[NFE]).either( "fish".toInt )
res2: Either[Throwable,Int] = Left(java.lang.NumberFormatException: For input string: "fish")
scala> catching(classOf[NFE]).either( "42".toInt )
res3: Either[Throwable,Int] = Right(42)
You can then use fold or map to an option or whatever else you like doing with eithers.
Note that you can define a single catcher and use it multiple times (so you don't need to create the catcher object every time you, for example, parse an integer):
scala> val catcher = catching(classOf[NFE])
catcher: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException)
scala> catcher.opt("42".toInt)
res4: Option[Int] = Some(42)
scala> catcher.opt("fish".toInt)
res5: Option[Int] = None
Edit: as Daniel points out in the comments, this still creates a temporary Catch[Option]; given the method signatures, there isn't an easy way to just have it trap exceptions and generate options without creating any extra objects. This reminds me why I write my own methods to do exactly that:
def optNFE[T](t: => T) = try { Some(t) } catch {case nfe: NFE => None}
optNFE( "fish".toInt ) // gives None
optNFE( "42".toInt ) // gives Some(42)
I use a more simple pattern when there is only one catch :
try{
return args.split(" ").exists(line.startsWith _)
}catch {
case _ =>{//generic exception
logger.error("Error with line ${line} for ${ex.message}")
throw _
}
}
I'm definitely not yet a Scala pro, and I guess you could find shorter stuff
加载中,请稍侯......
精彩评论