Использование утверждений против создания исключений?


38

Часто, когда я пишу функцию, я хочу убедиться, что входные данные для нее действительны, чтобы как можно раньше обнаружить такие ошибки (я считаю, что это называется предварительными условиями). Когда предварительное условие не выполняется, я всегда выбрасываю исключение. Но я начинаю сомневаться в том, что это лучшая практика, и если нет, то утверждения будут более уместными.

Так, когда я должен сделать что: когда уместно использовать утверждение и когда уместно бросить исключение?


3
Я думаю, что этот вопрос следует задавать в stackoverflow, хотя он, вероятно, задавался там дюжину раз, так что вы, возможно, уже найдете там много ответов.
— user281377 29.10.10

Ответы:


50

Утверждения должны использоваться только для проверки условий, которые, по логике, не могут быть ложными (читай: проверки работоспособности). Эти условия должны основываться только на входах, сгенерированных вашим собственным кодом. Любые проверки, основанные на внешних входах, должны использовать исключения.

Простое правило, которому я склонен следовать, - это проверка аргументов частных функций с помощью утверждений и использование исключений для аргументов открытых / защищенных функций.


Хорошее замечание об использовании исключений для внешних входов. Я также добавил бы к этому выходные данные - проблемы при попытке создать / записать в файл / базу данных и т. Д.
— ChrisF

13
И вы неизбежно обнаружите, что эти утверждения запускаются в производство. +1 для проверки личных вещей с утверждениями! Может быть, вы могли бы сказать «использовать утверждения, когда вы полностью контролируете входы»?
— Фрэнк Шиарар

1
В Java, по крайней мере, вы обычно должны включать проверку утверждений с параметром командной строки -ea. Это означает, что утверждения по сути являются запретными, если вы их явно не включили.
— Билл Мичелл

29

Утверждения используются для поиска ошибок программирования. Ваши программы должны работать так же хорошо, когда все утверждения удалены.

Исключения, с другой стороны, относятся к ситуациям, которые могут произойти, даже когда программа идеальна; они вызваны внешними воздействиями, такими как оборудование, сеть, пользователи и т. д.


Это довольно хороший способ выразить это. Если пользователь вводит что-то неверное, выведите исключение. Если введенные данные верны, но что-то все еще не так, выведите assert.
— Матин Улхак

3

Типичная практика программирования состоит в том, чтобы компилировать утверждения из сборок выпуска / выпуска. Утверждения помогут только во время внутреннего тестирования уловить ошибочные предположения. Вы не должны принимать на себя поведение внешних агентств, поэтому вы не должны утверждать о событиях из сети или пользователя. Также хорошей практикой является написание кода обработки для производственных сборок в случае сбоя утверждения.

Например, в C,

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

Исключения предназначены для встраивания в производственные сборки. Альтернативой для исключения является возвращение ошибки, а не утверждения.


2
Я не думаю, что было бы хорошей идеей ставить изящное поведение за то же условие. Неизбежно, поскольку изящное поведение существует только в рабочей версии, код, который должен был справляться с изящным поведением, будет плохо протестирован и вылетит так же плохо, как если бы не хуже, чем код, если бы он не охранялся.
— Себастьян Редл

0

Одна проблема с утверждениями для меня состоит в том, что они отключены по умолчанию в Java.

Мы используем стратегию «первый сбой», когда программе, которая могла работать без присмотра в течение многих лет, необходимо как можно раньше завершать работу, чтобы избежать повреждения данных в случае неверных данных (в неожиданной форме). Это то, для чего мы используем проверку, и, используя утверждения, мы в основном рискуем, что они не активны.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.