День семьсот пятнадцатый. #TypesAndLanguages
Довольно интересной показалась серия статей Types and Programming Languages от Adam Furmanek. Интересные наблюдения и тонкости языков программирования. Сегодня первая часть.
1. Не используйте return в блоке finally
Многие языки предоставляют конструкцию обработки исключений, обычно в виде блоков
Некоторые языки поддерживают дополнительный блок
Некоторые языки позволяют возвращать результат из блока
Результат кажется простым и логичным. Но что произойдет, если вы выбросите исключение, а затем используете return? Например, в Java:
Источник: https://blog.adamfurmanek.pl/2021/01/09/types-and-programming-languages-part-1/
Довольно интересной показалась серия статей Types and Programming Languages от Adam Furmanek. Интересные наблюдения и тонкости языков программирования. Сегодня первая часть.
1. Не используйте return в блоке finally
Многие языки предоставляют конструкцию обработки исключений, обычно в виде блоков
try и catch, хотя детали реализации различаются. Программисты обычно предполагают, что эти конструкции работают одинаково для разных языков. К сожалению, это неправда, и нюансы часто бывают сложны для понимания, когда дело доходит до крайних случаев.Некоторые языки поддерживают дополнительный блок
finally, который должен выполняться «несмотря ни на что» - независимо от того, было сгенерировано исключение или нет. Это, правда, не совсем так: есть много ситуаций, когда этот блок не может быть вызван, например, аварийное завершение приложения, ошибки нарушения доступа и т. д. Но сейчас не об этом.Некоторые языки позволяют возвращать результат из блока
finally. В следующем примере на Java последний return «побеждает» другие:public static void main (String[] args)Результат - 42, потому что это последнее возвращаемое значение. Такое же поведение можно видеть в Python, JS, возможно, и на других платформах. Примечательным исключением здесь является C#, который не позволяет использовать return в блоке finally, просто чтобы избежать этой путаницы.
throws java.lang.Exception {
System.out.println(foo());
}
public static int foo(){
try{
return 5;
}finally{
return 42;
}
}
Результат кажется простым и логичным. Но что произойдет, если вы выбросите исключение, а затем используете return? Например, в Java:
public static void main (String[] args)Результат – всё равно 42. Исключение «проглатывается». То же самое в JS:
throws java.lang.Exception {
System.out.println(foo());
}
public static int foo() {
try {
throw new RuntimeException(
"Это сообщение пропадает");
}finally{
return 42;
}
}
function foo(){
try{
throw "Это сообщение пропадает";
}finally{
return 42;
}
}
console.log(foo());
Python:def foo():В общем случае, никогда не используйте
try:
raise Exception("Это сообщение пропадает")
finally:
return 42
print(foo())
return в блоке finally. Это ломает механизм обработки исключений.Источник: https://blog.adamfurmanek.pl/2021/01/09/types-and-programming-languages-part-1/