Рішення про неперевірені винятки в Scala


17

Як програміст Java, я завжди критично ставився до Неперевірених винятків. В основному програмісти використовують його як шлях до кодування легкості, лише щоб потім створити проблеми. Також програми (хоча і неохайні) з перевіреними винятками є значно надійнішими порівняно з неперевіреними аналогами.

Дивно, але в Scala немає нічого, що називається перевіреними винятками. Усі перевірені та неперевірені Java перевіряються у Scala.

Яка мотивація цього рішення? Для мене це відкриває широке коло проблем при використанні будь-якого зовнішнього коду. І якщо випадково документація погана, це призводить до вбивства.


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 вибір параметра "Опція" як типу повернення, швидше за все, спричинить відповідність шаблонів, а не твердження If . Повернення Ніхто, а не Деякі в цьому стилі є тривіальним, а не складним. Менш хитрі розробники можуть не вибирати функції запису, які повертають алгебраїчні типи, але це інша річ. Нарешті, «ви навіть не можете повернутися з функції, коли захочете» - просто неправда.
йогобрюс

7

Перевірені винятки на Java - це не так вже й погано. Звичайно, ADT можуть бути кращим варіантом для Scala, але в Java перевірені винятки мають своє місце, і аргументований код є просто незрозумілим безглуздим незалежно від того, скільки блогів це повторили. Це в основному говорить про те, що вам слід із задоволенням ігнорувати важкі та, можливо, відновлювані умови, які можуть статися у вашій системі, оскільки система гвинтового типу, гарний код, робить вашу систему надійною автоматично. Таке міркування також пояснює , чому так багато Java кодеров добровільно перемістити свій код в XMLs (Spring, Maven і т.д. Я сумую досить частина , хоча тут).

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

Проблема з перевіреними винятками найкраще демонструється методом карт у списках:

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

Як коментувати карту за допомогою @throw? Якщо карта не отримує анотацію @throw сама по собі, імовірно, ви не можете передати їй жодну функцію, яка має @throw. Це ввело б громіздкі обмеження та відмінність способів використання карти. Все було б краще, якби ми якось констатували, що карта викидає всі винятки, які кидає її аргумент функції. Існують деякі системи ефектів, які можуть це виразити, але поки що кожне позначення, яке я бачив, занадто важке.

Лукас Ріц проводить деякі дослідження систем легкого впливу, які можна було б використовувати для стислого і точного вираження типу карти та інших загальних функцій. Це дослідження, тому наразі незрозуміло, до якої міри ми досягнемо успіху і скільки цього можна вкласти в Scala. В ідеалі ми зможемо додати його в якийсь момент у вигляді додаткової системи типу. Але робити конкретні прогнози набагато рано.

Ура

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


2

Якщо ви хочете отримати ефективність, вам доведеться відмовитися .. точність / контроль <- мені потрібне краще слово для цього.

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

Я не знаю, чи отримую я саме те, що ви просите, але це, на мою думку, найбільш очевидна причина.

Ну, я трохи подивився, і хтось написав про трагедію винятків з перевірки .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.