История изменений
Исправление kaldeon, (текущая версия) :
В Go, конечно, тоже придётся попрыгать. И return, и throw – похожие механизмы прерывания потока выполнения. Но в случае с Go тебе достаточно подняться на один уровень вверх и ты уже стоишь на строке, которая пробрасывает или обрабатывает ошибку. “return fmt.Errorf” — это тоже полезная информация, сразу сообщающая «не здесь». В Java недостаточно подняться на один уровень вверх, придётся ещё проверить список throws, окружающий try {} catch блок, который дополнительно зависит от иерархии типов. Нет локальности проброса как лексического понятия, то есть возможности понять поведение кода, глядя только на текущую функцию и её непосредственное окружение, а имеющаяся лексическая информация вроде throws неполна.
Исключения изначально были созданы для обработки исключительных ситуаций. Именно поэтому им позволено так легко ломать поток выполнения. Но не все ошибки должны быть исключительными. Нет ничего исключительного, достойного сказать «не моя проблема», если, например, файл вдруг не открылся. Java попыталась адаптировать исключения, сделав их более контролируемыми, но тем самым смешала два принципиально разных понятия в одну неразличимую кучу. (Unchecked исключения делают проблему ещё острее.)
А централизованно.
Например, ловим мы IOException. Его может выбросить бд, устанавливающая соединение через соккет, или запись в логи. При записи в логи не нужно прерывать работу метода. Это не редкость. И в чём преимущество централизации?
Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.
Да, Java даёт определённые гарантии, но при этом поощряет перекладывание исключения в throws. Учитывая то, кто каллером может быть потенциально кто угодно, всегда есть надежда, что где-то в глубине есть могучий Атлант try-catch, который точно знает что делать с твоим исключением.
Но и в Go тоже есть гарантии. Ты не можешь просто написать data, err := hello(), не обработав err (компилятор запретит). Как раз нужно приложить усилие, чтобы НЕ обработать err — написать странную конструкцию data, _ := hello(). Так делают, но крайне редко, в проде почти никогда, потому что компилятор постоянно сталкивает программиста лбом с ошибками.
(Функции, возвращающие ошибку как один аргумент — меньшинство, но да, это недостаток. Однако, здесь мы переходим от темы про исключения к теме про result.)
Примерно как в баше, лол.
Очень большое преувеличение. В Go ошибки – это значения. Соответственно, улучшая работу со значениями (например, запретом на неиспользуемые переменные), мы улучшаем обработку ошибок. В баше ошибки – коды возврата, то есть протекающая абстракция ОС, которую мы можем получить магической переменной $?. Функции в шелле не возвращают ошибки как значения (строго говоря, функция в шелле вообще ничего не «возвращает» в смысле обычных языков).
информативность стектрейса на порядок выше какой-то рандомной строчки в Go
Никто не запрещает захватывать стек-трейс в Go. Никто, вроде, не считает это неправильным.
Исправление kaldeon, :
В Go, конечно, тоже придётся попрыгать. И return, и throw – похожие механизмы прерывания потока выполнения. Но в случае с Go тебе достаточно подняться на один уровень вверх и ты уже стоишь на строке, которая пробрасывает или обрабатывает ошибку. “return fmt.Errorf” — это тоже полезная информация, сразу сообщающая «не здесь». В Java недостаточно подняться на один уровень вверх, придётся ещё проверить список throws, окружающий try {} catch блок, который дополнительно зависит от иерархии типов. Нет локальности проброса как лексического понятия, то есть возможности понять поведение кода, глядя только на текущую функцию и её непосредственное окружение, а имеющаяся лексическая информация вроде throws неполна.
Исключения изначально были созданы для обработки исключительных ситуаций. Именно поэтому им позволено так легко ломать поток выполнения. Но не все ошибки обязаны быть исключительными. Нет ничего исключительного, достойного сказать «не моя проблема», если, например, файл вдруг не открылся. Java попыталась адаптировать исключения, сделав их более контролируемыми, но тем самым смешала два принципиально разных понятия в одну неразличимую кучу. (Unchecked исключения делают проблему ещё острее.)
А централизованно.
Например, ловим мы IOException. Его может выбросить бд, устанавливающая соединение через соккет, или запись в логи. При записи в логи не нужно прерывать работу метода. Это не редкость. И в чём преимущество централизации?
Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.
Да, Java даёт определённые гарантии, но при этом поощряет перекладывание исключения в throws. Учитывая то, кто каллером может быть потенциально кто угодно, всегда есть надежда, что где-то в глубине есть могучий Атлант try-catch, который точно знает что делать с твоим исключением.
Но и в Go тоже есть гарантии. Ты не можешь просто написать data, err := hello(), не обработав err (компилятор запретит). Как раз нужно приложить усилие, чтобы НЕ обработать err — написать странную конструкцию data, _ := hello(). Так делают, но крайне редко, в проде почти никогда, потому что компилятор постоянно сталкивает программиста лбом с ошибками.
(Функции, возвращающие ошибку как один аргумент — меньшинство, но да, это недостаток. Однако, здесь мы переходим от темы про исключения к теме про result.)
Примерно как в баше, лол.
Очень большое преувеличение. В Go ошибки – это значения. Соответственно, улучшая работу со значениями (например, запретом на неиспользуемые переменные), мы улучшаем обработку ошибок. В баше ошибки – коды возврата, то есть протекающая абстракция ОС, которую мы можем получить магической переменной $?. Функции в шелле не возвращают ошибки как значения (строго говоря, функция в шелле вообще ничего не «возвращает» в смысле обычных языков).
информативность стектрейса на порядок выше какой-то рандомной строчки в Go
Никто не запрещает захватывать стек-трейс в Go. Никто, вроде, не считает это неправильным.
Исправление kaldeon, :
В Go, конечно, тоже придётся попрыгать. И return, и throw – похожие механизмы прерывания потока выполнения. Но в случае с Go тебе достаточно подняться на один уровень вверх и ты уже стоишь на строке, которая пробрасывает или обрабатывает ошибку. “return fmt.Errorf” — это тоже полезная информация, сразу сообщающая «не здесь». В Java недостаточно подняться на один уровень вверх, придётся ещё проверить список throws, окружающий try {} catch блок, который дополнительно зависит от иерархии типов. Нет локальности проброса как лексического понятия, то есть возможности понять поведение кода, глядя только на текущую функцию и её непосредственное окружение, а имеющаяся лексическая информация вроде throws неполна.
Исключения изначально были созданы для обработки исключительных ситуаций. Именно поэтому им позволено так легко ломать поток выполнения. Но не все ошибки обязаны быть исключительными. Нет ничего исключительного, достойного сказать «не моя проблема», если, например, файл вдруг не открылся. Java попыталась адаптировать исключения, сделав их более контролируемыми, но тем самым смешала два принципиально разных понятия в одну неразличимую кучу. (Unchecked исключения делают проблему ещё острее.)
А централизованно.
Например, ловим мы IOException. Его может выбросить бд, устанавливающая соединение через соккет, или запись в логи. При записи в логи не нужно прерывать работу метода. Это не редкость. И в чём преимущество централизации?
Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.
Да, Java даёт определённые гарантии, но при этом поощряет перекладывание исключения в throws. Учитывая то, кто каллером может быть потенциально кто угодно, всегда есть надежда, что где-то в глубине есть могучий Атлант try-catch, который точно знает что делать с твоим исключением.
Но и в Go тоже есть гарантии. Ты не можешь просто написать data, err := hello(), не обработав err (компилятор запретит). Как раз нужно приложить усилие, чтобы НЕ обработать err — написать странную конструкцию data, _ := hello(). Так делают, но крайне редко, в проде почти никогда.
(Функции, возвращающие ошибку как один аргумент — меньшинство, но да, это недостаток. Однако, здесь мы переходим от темы про исключения к теме про result.)
Примерно как в баше, лол.
Очень большое преувеличение. В Go ошибки – это значения. Соответственно, улучшая работу со значениями (например, запретом на неиспользуемые переменные), мы улучшаем обработку ошибок. В баше ошибки – коды возврата, то есть протекающая абстракция ОС, которую мы можем получить магической переменной $?. Функции в шелле не возвращают ошибки как значения (строго говоря, функция в шелле вообще ничего не «возвращает» в смысле обычных языков).
информативность стектрейса на порядок выше какой-то рандомной строчки в Go
Никто не запрещает захватывать стек-трейс в Go. Никто, вроде, не считает это неправильным.
Исходная версия kaldeon, :
В Go, конечно, тоже придётся попрыгать. И return, и throw – похожие механизмы прерывания потока выполнения. Но в случае с Go тебе достаточно подняться на один уровень вверх и ты уже стоишь на строке, которая обрабатывает ошибку. “return fmt.Errorf” — это тоже полезная информация, сразу сообщающая «не здесь». В Java недостаточно подняться на один уровень вверх, придётся ещё проверить список throws, окружающий try {} catch блок, который дополнительно зависит от иерархии типов. Нет локальности проброса как лексического понятия, то есть возможности понять поведение кода, глядя только на текущую функцию и её непосредственное окружение, а имеющаяся лексическая информация вроде throws неполна.
Исключения изначально были созданы для обработки исключительных ситуаций. Именно поэтому им позволено так легко ломать поток выполнения. Но не все ошибки обязаны быть исключительными. Нет ничего исключительного, достойного сказать «не моя проблема», если, например, файл вдруг не открылся. Java попыталась адаптировать исключения, сделав их более контролируемыми, но тем самым смешала два принципиально разных понятия в одну неразличимую кучу. (Unchecked исключения делают проблему ещё острее.)
А централизованно.
Например, ловим мы IOException. Его может выбросить бд, устанавливающая соединение через соккет, или запись в логи. При записи в логи не нужно прерывать работу метода. Это не редкость. И в чём преимущество централизации?
Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.
Да, Java даёт определённые гарантии, но при этом поощряет перекладывание исключения в throws. Учитывая то, кто каллером может быть потенциально кто угодно, всегда есть надежда, что где-то в глубине есть могучий Атлант try-catch, который точно знает что делать с твоим исключением.
Но и в Go тоже есть гарантии. Ты не можешь просто написать data, err := hello(), не обработав err (компилятор запретит). Как раз нужно приложить усилие, чтобы НЕ обработать err — написать странную конструкцию data, _ := hello(). Так делают, но крайне редко, в проде почти никогда.
(Функции, возвращающие ошибку как один аргумент — меньшинство, но да, это недостаток. Однако, здесь мы переходим от темы про исключения к теме про result.)
Примерно как в баше, лол.
Очень большое преувеличение. В Go ошибки – это значения. Соответственно, улучшая работу со значениями (например, запретом на неиспользуемые переменные), мы улучшаем обработку ошибок. В баше ошибки – коды возврата, то есть протекающая абстракция ОС, которую мы можем получить магической переменной $?. Функции в шелле не возвращают ошибки как значения (строго говоря, функция в шелле вообще ничего не «возвращает» в смысле обычных языков).
информативность стектрейса на порядок выше какой-то рандомной строчки в Go
Никто не запрещает захватывать стек-трейс в Go. Никто, вроде, не считает это неправильным.