php - ¿Por qué usar la palabra clave "finalmente"?
error-handling try-catch (2)
Esta pregunta ya tiene una respuesta aquí:
- ¿Por qué usamos finalmente bloques? 10 respuestas
Entiendo para qué se usa la palabra clave "finalmente" en varios idiomas, sin embargo, me cuesta entender por qué la usarías fuera de que exista una preferencia de formato en el gusto.
Por ejemplo, en PHP:
try {
possibleErrorThrownFunction();
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
}
finally {
// run this code every single time regardless of error or not
}
¿Cuál es la diferencia entre lo que está haciendo este código y esto?
try {
possibleErrorThrownFunction();
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
}
// run this code every single time regardless of error or not
¿Esa última línea no siempre se ejecuta de todos modos debido a que se detecta el error? En cuyo caso, no hay ningún caso para usar realmente, a menos que solo desee mantener un formato de estilo de código.
Un ejemplo de un caso en el que una declaración
finally
es necesaria y distinta de simplemente poner código después de las declaraciones try / catch sería útil si me falta algo aquí.
Respuesta corta
Finally
, se garantiza que los bloques se ejecuten sin importar lo que suceda dentro de los bloques
try
y
catch
, antes de permitir que el programa se bloquee.
Esto se explica aquí: https://www.php.net/manual/en/language.exceptions.php aunque la explicación no es particularmente detallada.
Algunos detalles más
Un ejemplo que me viene a la cabeza es si se trata de flujos de entrada / salida o algo similar que debe cerrarse después de su uso para evitar una pérdida de memoria. Para usar su ejemplo:
try {
memoryUser.startReading(someFileOrSomething);
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
invisibleBug.whoops(); // i.e. something goes wrong in this block
}
memoryUser.Close(); // because something went wrong in the catch block,
// this never runs, which, in this case, causes a memory leak
En este caso, envolviendo el
memoryUser.Close();
en un bloque
finally
se aseguraría de que esa línea se ejecute antes de que explote el resto del programa, evitando la pérdida de memoria incluso en un fallo catastrófico.
TL; DR
Por lo tanto, la mayoría de las veces, la gente coloca el bloque finalmente allí para garantizar que se ejecute una línea importante, incluso si pasan por alto algo en los bloques de captura. Así es como siempre lo he visto usado.
Esperemos que esto ayude :)
Lo especial de un bloque
finally {}
es que
siempre se
ejecutará al final del bloque
try {}
.
-
Se ejecutará si el código en el bloque
try {}
se completa con éxito. -
Se ejecutará si el código en el bloque
try {}
arroja una excepción que fue atrapada por uncatch {}
. (finally {}
ejecuta después de lacatch {}
.) -
Se ejecutará si el código en el bloque
try {}
arroja una excepción que no fue manejada por ningún bloquecatch {}
, o si no hubo ninguno. (El bloquefinally {}
se ejecuta antes de que la excepción se propague a la persona que llama). -
Se ejecutará si el código en el bloque
try {}
arroja una excepción, y el código en elcatch {}
arroja otra excepción (o vuelve a lanzar la misma excepción). -
Incluso se ejecutará si el código en el bloque
try {}
, o en un bloquecatch {}
, usareturn
. (Al igual que con una excepción no detectada, elfinally {}
ejecuta antes de que la función realmente regrese). ¡El bloquefinally {}
puede incluso usar el propioreturn
, y su valor de retorno anulará el valor que el otro bloque intentó devolver!
(Hay un caso extremo en el que
finally {}
no se ejecutará un bloque
finally {}
, y es si todo el proceso se destruye, por ejemplo, al ser asesinado o al llamar a
exit()
o
die()
.)