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

38

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

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

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

Ответы:

50

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

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

Примечание для себя - придумай имя
источник
Хорошее замечание об использовании исключений для внешних входов. Я также добавил бы к этому выходные данные - проблемы при попытке создать / записать в файл / базу данных и т. Д.
ChrisF
13
И вы неизбежно обнаружите, что эти утверждения запускаются в производство. +1 для проверки личных вещей с утверждениями! Может быть, вы могли бы сказать «использовать утверждения, когда вы полностью контролируете входы»?
Фрэнк Шиарар
1
В Java, по крайней мере, вы обычно должны включать проверку утверждений с параметром командной строки -ea. Это означает, что утверждения по сути являются запретными, если вы их явно не включили.
Билл Мичелл
29

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

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

user281377
источник
Это довольно хороший способ выразить это. Если пользователь вводит что-то неверное, выведите исключение. Если введенные данные верны, но что-то все еще не так, выведите 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
  ...
}

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

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

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

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


источник