2011-10-17 10 views
19

He leído y experimentado con la función Scala 2.9 try ... catch, y me hace pensar en las posibilidades. ¿Para qué lo usaría para otro que no sea guardar un par de líneas de código?¿Cuáles son los casos de uso para probar Scala 2.9 ... generalización de capturas?

Scala 2.9 Final Release Notes

+0

No estoy seguro de que lo usaría ... pero puede usar * any * (conforme) PartialFunction ... ¿ha manejado un error unificado en otro lugar? (Diga 'ignoreTheseSillyClosableExceptions'.) Además," es genial "que Scala pueda expresarlo así ;-) –

+0

Para inspiración: Paul Phillips brindó un ejemplo motivacional cuando implementó esto: http://www.scala-lang.org/node/8070 –

+3

La pregunta sería mejor con un ejemplo o al menos un enlace. – ziggystar

Respuesta

24

El caso de uso es ser capaz de tener el manejo de toda la aplicación de error genérico. Supongamos que desea manejar todos los FileNotFoundException s en su aplicación enviando un correo electrónico a un administrador. Anteriormente, habría que hacerlo de esta manera:

// Globally 
val fileNotFound: PartialFunction[Throwable, Unit] = { 
    case e: FileNotFoundException => 
    // Create report and send the e-mail 
} 

// On each try-catch-block 
try { 
    // Open file 
} 
catch { 
    case fnf: FileNotFoundException => fileNotFound(fnf) 
} 

Ahora que acaba de hacer:

try { 
    // Open file 
} catch fileNotFound 

Esto también tiene la ventaja agradable que se puede enlazar varios controladores de tales excepciones usando el método de orElse funciones parciales:

val fileErrors = fileNotFound orElse endOfFile orElse invalidFormat 

Y luego simplemente use eso en todos los lugares donde necesite manejo de excepciones de archivos. Tal controlador de errores se puede combinar dinámicamente en función del archivo de configuración para la aplicación, por ejemplo. Esto es mucho menos engorroso que la coincidencia de patrones en todas partes y llama al manejador correcto.

Una cosa útil que podría ser pimped en la parte superior de funciones parciales es el operador andAlso, que actúa como un operador de secuencia en dos funciones parciales. Esto sería útil cuando desee realizar un manejo de errores específico de un bloque de prueba en particular después de haber realizado el manejo genérico de errores.

implicit def pf2ops(pf: PartialFunction[Throwable, Unit]) = new { 
    def andAlso(localpf: PartialFunction[Throwable, Unit]) = new PartialFunction[Throwable, Unit] { 
    def apply(t: Throwable) = { 
     if (pf.isDefinedAt(t)) pf(t) 
     localpf(t) 
    } 
    def isDefinedAt(t: Throwable) = pf.isDefinedAt(t) || localpf.isDefinedAt(t) 
    } 
} 

Y entonces usted puede hacer esto:

scala> try { 
    | throw new java.io.FileNotFoundException 
    | } catch fnf andAlso { 
    | case e: Exception => println("I don't know, but something is specific to this particular block.") 
    | } 
I don't know, but something is specific to this particular block. 

Creo que se puede jugar más allá con la semántica exacta y el significado (y el nombre) de andAlso.

+0

Una respuesta agradable - Creo que el y también la parte era la parte que me faltaba. – Seth

7

Buena respuesta por axel22, pero creo que el verdadero motivo de su introducción es otra cosa. El manejo try/catch/finally presentó un caso especial . Usó un literal de función parcial, pero en realidad no podría reemplazarlo con una función parcial. Ahora, catch acaba de recibir una función parcial, y un caso especial más en el idioma se ha ido.

+0

Me gusta esta respuesta también :) – Seth

+0

Esto realmente confirma mi razonamiento inicial, que esta es principalmente una característica de "limpieza". – Seth

+0

De acuerdo, es el principio de uniformidad en su mejor expresión, una construcción generalizada que tiene usabilidad como consecuencia. – axel22

Cuestiones relacionadas