Решение для непроверенных исключений в Scala

17

Как программист Java, я всегда критиковал Unchecked Exceptions. В основном программисты используют его как средство для легкого кодирования, чтобы потом создавать проблемы. Кроме того, программы (хотя и неопрятные) с проверенными исключениями намного надежнее по сравнению с непроверенными аналогами.

Удивительно, но в Scala нет ничего, что называется Проверенные исключения. Все проверенные и не проверенные Java не проверяются в Scala.

Какова мотивация этого решения? Для меня это открывает широкий спектр проблем при использовании любого внешнего кода. И если случайно документация плохая, это приводит к УБИЙСТВУ.

Jatin
источник
11
Как программист на Java, я всегда критиковал проверенные исключения. Неопрятный код никогда не бывает надежным.
Майкл Боргвардт

Ответы:

28

Проверенные исключения чаще всего считаются неудачными. Обратите внимание, что ни один из языков, созданных после Java, не принял их. См. Http://www.artima.com/intv/handcuffs2.html , http://googletesting.blogspot.ru/2009/09/checked-exceptions-i-love-you-but-you.html , http: / /www.mindview.net/Etc/Discussions/CheckedExceptions и т. д.

В частности, они неразложимы (кроме как путем возврата throws Exception).

В Scala у вас есть лучший вариант: с помощью алгебраических типов для возвращаемых значений , таких как Option[T], Either[Exception, T], ваш собственный тип , если вы хотите, чтобы пользователь на конкретные случаи ручки (например , вместо

def foo: Int // throws FileNotFoundException, IllegalStateException

у тебя есть

sealed trait FooResult
case class Success(value: Int) extends FooResult
case class FileNotFound(file: File) extends FooResult
case object IllegalState extends FooResult

def foo: FooResult

и потребитель теперь обязан обрабатывать все результаты)

Для работы с внешним кодом, который выдает исключения, у вас есть scala.util.control.exceptionили scala.util.Try(начиная с Scala 2.10).

Алексей романов
источник
4
Никогда не понимал, что большинство людей не обрабатывают аргумент проверенных исключений . Большинство людей не являются хорошими разработчиками. Я гарантирую, что большинство разработчиков все равно не будут обрабатывать ошибки. На самом деле, try..catchкажется, гораздо более читабельным, чем if. Более того, я также могу гарантировать, что те же самые разработчики не собираются писать код, который возвращает результат ошибки - слишком сложный в Scala - вы даже не можете вернуться из функции, когда захотите (как в Pascal)
Pijusn
5
Я нахожу, что ваш комментарий сбивает с толку и не хватает доказательств, @Pius. В Scala выбор Option в качестве возвращаемого типа, скорее всего, приведет к сопоставлению с образцом, а не к операторам If . Возвращать None, а не Some в этом стиле, тривиально, а не сложно. Менее осведомленные разработчики могут не захотеть писать функции, которые возвращают алгебраические типы, но это совсем другое. Наконец, «вы не можете даже вернуться из функции, когда захотите» - просто не соответствует действительности.
Брюс
7

Проверенные исключения в Java не так уж плохи. Конечно, ADT могут быть лучшим вариантом для Scala, но в Java проверенные исключения имеют свое место, и аргумент аккуратного кода является просто бессмысленным бессмысленным, независимо от того, сколько блогов повторялось это. В основном это говорит о том, что вы должны с радостью игнорировать серьезные и, возможно, исправимые условия, которые могут возникнуть в вашей системе, потому что система винтового типа, красивый код делает вашу систему автоматически надежной. Такое рассуждение также объясняет, почему так много Java-кодеров добровольно переносят свой код в XML (Spring, Maven и т. Д. Я скучаю по хорошему Хотя здесь часть).

Причина отсутствия проверенных исключений в Scala, приведенная М. Одерским ниже http://www.scala-lang.org/old/node/8787.html , неудивительно отличается и имеет смысл.

Проблема с проверенными исключениями лучше всего демонстрируется методом map в списках:

def map[B](f: A => B): List[B]

Как аннотировать карту с помощью @throws? Если карта сама по себе не получает аннотацию @throws, то, вероятно, вы не сможете передать ей функцию, которая имеет @throws. Это вводит громоздкие ограничения и различия в способах использования карты. Было бы лучше, если бы мы могли как-то заявить, что карта генерирует все исключения, которые выдает ее аргумент функции. Есть некоторые системы эффектов, которые могут выразить это, но пока что все обозначения, которые я видел, слишком тяжелые.

Лукас Ритц (Lukas Rytz) проводит исследование легких систем эффектов, которые можно использовать для краткого и точного выражения типа карты и других общих функций. Это исследование, поэтому в настоящее время неясно, в какой степени мы добьемся успеха и сколько из этого может быть вложено в Scala. В идеале, мы сможем добавить его в какой-то момент в качестве необязательной системы типов. Но слишком рано делать конкретные прогнозы.

ура

Не уверен, но я думаю, что лямбды Java 8 также ограничены непроверенными исключениями.Методы в большинстве (всех?) Новых функциональных интерфейсов в JDK 8 ( java.util.function.*) также не объявляют непроверенные исключения.

woky
источник
2

Если вы хотите повысить эффективность, вы должны отказаться от… точности / контроля <- мне нужно более подходящее слово для этого.

Скала расположена к вершине, насколько абстракция идет. Если одной из целей Scala является избавление от надоедливого стандартного кода, то очевидным местом для рассмотрения является обработка исключений в Java. Если вы хотите написать быстрый код на языке Java, просто продолжайте бросать проверенные исключения, пока они не сработают main()и не станут фактически непроверенными.

Я не знаю, правильно ли я понимаю, что вы спрашиваете, но это самая очевидная причина, по моему мнению.

Ну, я немного посмотрел, и кто-то написал о трагедии проверки исключений .

Дэвид Кауден
источник