28 votos

Scala captura de confusión

Recientemente he visto un código como este:

val maybeInt = catching(classOf[NFE]) opt arg.toInt

¿Qué es esto opt? Una Opción? ¿Por qué no es el uso de getOrElse para extraer el valor? En el código anterior, maybeInt Ninguno si un NumberFormatException se tira?

32voto

Rex Kerr Puntos 94401

catching parece que es algún tipo de llamada de método, ¿no? Lo es, pero en realidad devuelve una instancia de una clase Catch; no tomar directamente un argumento. Esta clase tiene dos métodos que son especialmente útiles para tratar con excepciones (y varios más para la captura de múltiples excepciones). La primera es

def opt [U >: T] (body: ⇒ U) : Option[U]

que se utiliza aquí--que dar algo, que puede lanzar una excepción, y volverá Some(result) si todo ha ido bien, y None si el objetivo de la excepción fue capturada:

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)

Usted puede entonces tratar este con map o filter o getOrElse o cualquier otra cosa que utilizar para tratar con opciones.

El otro método útil es either, que devuelve una instancia de Left(exception) si se produce una excepción, y un Right(result) si no:

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)

Usted puede utilizar fold o mapa a una opción o cualquier otra cosa que te gusta hacer con eithers.

Tenga en cuenta que usted puede definir un único receptor y utilizar varias veces (por lo que no necesita para crear el catcher objeto cada vez que, por ejemplo, analizar un 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

Edit: como Daniel señala en los comentarios, esto crea un temporal Catch[Option]; dado el método de firmas, no hay una manera fácil sólo tienes que atrapar excepciones y generar opciones sin crear objetos extra. 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)

0voto

Nicolas Zozol Puntos 1514

Yo utilice un patrón simple cuando sólo hay un problema :

 try{
      return args.split(" ").exists(line.startsWith _)
 }catch {
    case _ =>{//generic exception
      logger.error("Error with line ${line} for ${ex.message}")
      throw _
    }    
 }

Definitivamente, no soy todavía un Scala pro, y yo creo que se podría encontrar más cortos cosas

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X