2011-12-09 3 views
14

Los dos siguiente código genera resultado diferente:"volver" y "try-catch-finally" Evaluación de bloques de la Scala

def x = try{ 
    true 
} finally false 

invocación x se true

def y:Boolean = try{ 
    return true 
} finally { 
    return false 
} 

invocan y obtiene false

la versión return se comporta igual que Java.

Personalmente, nunca uso 'return' en scala. Pero es bueno saber cómo evalúa Scala el valor de un bloque try-catch-finally. Gracias.

Respuesta

13

Tiene should not tiene una instrucción return en un bloque finally (aunque técnicamente está permitido, al menos en Java, C# por ejemplo lo prohíbe).

Si el bloque Scala finally tuviera un retorno implícito, eso siempre afectaría el valor de retorno previsto. Entonces eso no tiene sentido.

Pero supongo que no puede ayudarte si lo escribes explícitamente de esa manera.

+0

Pero, ¿qué es "una devolución implícita"? – xiefei

+0

"Retorno implícito": Tal vez la palabra incorrecta, pero lo que quise decir es que Scala usa el resultado de la última línea del bloque de código como el valor de retorno para el bloque. – Thilo

+2

Thilo tiene razón. Poner una declaración 'return' en un bloque' finally' debe considerarse un error, y en realidad no está permitido. 'Finally' es para limpiar cosas sin importar si el cuerpo del método tiene éxito o lanza una excepción. ¡No es el lugar para decidir un valor de retorno! Por lo tanto, el cuerpo de la cláusula 'finally' se toma para evaluar' Unidad'. En su primer ejemplo, el 'falso' se convierte implícitamente en' Unidad'. –

9

De acuerdo con la especificación de lenguaje Scala:

Un try expresión try {b} e se evalúa por último el bloque b. Si la evaluación de b no provoca una excepción, se evalúa la expresión e. Si se produce una excepción durante la evaluación de e, la evaluación de la expresión de prueba se cancela con la excepción lanzada. Si no se arroja ninguna excepción durante la evaluación de e, se devuelve el resultado de b como resultado de la expresión try.

Este comportamiento parece estar en contradicción con esa especificación. Supongo que, dado que 'return' causa un retorno inmediato de la función , esto da como resultado la anulación del comportamiento estándar para un bloque try. Un ejemplo iluminando es:

def z : Boolean = { 
    val foo = try { true } finally { return false } 
    true 
} 

Invocando z rendimientos false.

+3

Sí, al regresar de un bloque final se rompe el control de flujo. Debería estar prohibido – Thilo

+11

'return' siempre rompe el control de flujo. Solo se pone especialmente raro en ese caso. – Debilski

+0

Está de acuerdo con la especificación. El siguiente párrafo dice que se espera que el tipo de 'e' se ajuste a' Unidad', lo que significa que 'e' se evalúa solo por sus efectos secundarios. Cuando 'e' es' retorno ...', las reglas de evaluación dicen que el flujo de control deja el método ejecutado actualmente, devolviendo el argumento dado. –

Cuestiones relacionadas