Використовувати твердження проти викидання винятків?


38

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

Тож коли я повинен робити що: коли доцільно використовувати твердження і коли доцільно кинути виняток?


3
Я думаю, що це запитання слід задавати під час stackoverflow, хоча його, напевно, задавали там десяток разів, тож ви вже можете знайти багато відповідей.
— користувач281377

Відповіді:


50

Твердження повинні використовуватися лише для перевірки умов, які повинні бути логічно неможливими помилковими (читайте: перевірки здорового стану). Ці умови повинні базуватися лише на входах, створених вашим власним кодом. Будь-які перевірки, засновані на зовнішніх входах, повинні використовувати винятки.

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


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

13
І неминуче ви знайдете ті твердження, що спрацьовують у виробництві. +1 для перевірки приватних речей із відступками! Можливо, ви могли б сказати "використовувати твердження, коли ви повністю контролюєте вхідні дані"?
— Френк Ширар

1
У Java, як мінімум, типово потрібно включити перевірку твердження за допомогою параметра -ea командного рядка. Це означає, що твердження фактично відсутні, якщо ви прямо не включите їх.
— Білл Мішелл

29

Твердження використовуються для пошуку помилок програмування. Ваші програми повинні працювати так само добре, коли всі твердження видалені.

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


Це досить непоганий спосіб. Якщо користувач вводить щось неправильне, киньте виняток. Якщо введення правильне, але щось все-таки не так, киньте заяву.
— Матін Ульхак

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.