catching
Parece que es una especie de método de llamada, ¿no? Lo es, pero en realidad devuelve una instancia de una clase Catch
; no toma directamente un argumento. Esta clase tiene dos métodos que son particularmente útiles para tratar con excepciones (y varios más para detectar múltiples excepciones). La primera es
def opt [U >: T] (body: ⇒ U) : Option[U]
que está siendo utilizado aquí - le das algo que puede lanzar una excepción, y volverá Some(result)
si todo ha ido bien, y si la excepción None
objetivo fue capturado:
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)
A continuación, puede tratar esto con map
o filter
o getOrElse
o cualquier otra cosa que use para tratar las opciones.
El otro método útil es either
, que devuelve una instancia de Left(exception)
si se produce una excepción, y una Right(result)
si no fuera:
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)
continuación, puede utilizar fold
o un mapa a una opción o lo que sea más te gusta hacer con eithers.
Tenga en cuenta que puede definir un único receptor y poder usarlo varias veces (por lo que no es necesario para crear el objeto receptor cada vez que, por ejemplo, analizar un número entero):
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
Editar: como Daniel señala en los comentarios, esto todavía crea un Catch[Option]
temporal; dadas las firmas de método, no hay una manera fácil de hacer que atrape excepciones y genere opciones sin crear ningún objeto adicional. Esto me recuerda por qué escribo mis propios métodos para hacer exactamente eso:
def optNFE[T](t: => T) = try { Some(t) } catch {case nfe: NFE => None}
optNFE("fish".toInt) // gives None
optNFE("42".toInt) // gives Some(42)
¡Oye, ese código es familiar! :-) –
Me lo imaginaba :) – Geo