Чому помилки в мовах програмування названі як "Виняток", а не як "Помилка"?


45

Я фактично про це думав насправді. Я сам не є носієм англійської мови, але все-таки маю багаторічний досвід програмування, і мене це завжди просили. Чому він названий як Виняток, але не Помилка, оскільки вони є помилками.

Це могло бути PageNotFoundErrorзамість PageNotFoundException.


41
Не всі виняткові ситуації є помилками.
Ендрю Т Фіннелл

15
Це різниця між повертанням автомобіля та аварією автомобіля.
Всесвітній інженер

6
Ви просто говорите про найменування конкретних класів виключень? Потім зауважте, що в деяких екосистемах вони називаються XYError- наприклад, в Python.

6
Зауважте, у Java є клас Помилка, який успадковується від Throwable. Докладніше див. Docs.oracle.com/javase/1.4.2/docs/api/java/lang/Error.html для отримання більш детальної інформації. Ви також можете перевірити категорію "Прямі відомі підкласи".
luiscubal

Я хотів би сказати, що ця загадка не має нічого спільного з англійською. Це скоріше логічна категоризація будь-якої мови, якою ви говорите.
שינתיא אבישגנת

Відповіді:


59

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

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


27
Хоча використання механізмів винятку в якості потоку управління може бути заплутаним, і я думаю, що це, як правило, нахмурене.
ChaosPandion

11
@ChaosPandion: Залежить від мови / культури.
amara

11
@DocBrown: Я одного разу написав вирішувач судоку, який виконує рекурсивний пошук, який відхиляє, коли не вдається знайти рішення в поточній спробі і повторюю з іншим значенням; і коли рішення знайдено, воно викидає виняток, що містить розчин. Проблема тут - це "нормальна" ситуація, а успіх - "виняткова" ситуація; а оскільки в розв'язувальнику, де він дзвонить, є кілька точок, без використання винятку вам доведеться писати багато котлів, щоб перевірити, чи повертається виклик після успішного пошуку чи від невдалого пошуку.
Лежати Райан

5
@Falcon: так, ви можете просто повернути "готове" значення, що означає щоразу, коли ви повторюєте, вам доведеться це робити: for (...) { if (func() == finished) { return finished; } else { itfailedsocheckanother(); }}але враховуючи, що в коді є кілька точок, де функція () функціонує (), рішення, що не має винятків, стає щораз меншою, коли ви додаєте більше рекурсії. Це те, що я називаю вантажним культовим програмуванням, воно, по суті, імітує винятки в мові, яка вже є, тому що лідер культу каже, що "не повинні використовувати винятки".
Лежати Райан

8
@Falcon: А ... аргумент "запас виглядає як Goto", що аргументи працюють для того, щоб сказати, що ви не повинні використовувати цикли, або якщо заяви або функція викликає, тому що "всі вони схожі на gotos". Повернення успіху за винятком - лише WTF, якщо ви асоціюєте виняток з помилками. Для мене, коли використовується таким чином, блок пробного захоплення - це як "обіцянка повернутися сюди після тривалої подорожі", поведінка спроби, крім + кидання, дуже схоже на функцію-дзвінки + повернення, за винятком набагато довші подорожі, які можуть залучати дуже глибокий стек викликів, коли ви закінчили пошуки рішення.
Лежати Райан

21

Механізм винятків не завжди використовується для сигналізації про помилки. Винятки викидаються із звичайних ситуацій, для яких потрібен окремий шлях коду для обробки, включаючи помилки. Наприклад, користувач, який надає ім'я файлу, який не існує, або вводить літеру замість цифри в числовому полі, є винятковими ситуаціями, що вимагають особливої ​​обробки, але це не помилки.

У деяких середовищах програмування, таких як Java, Errorнадаються спеціальні об'єкти для повідомлення про "справжні помилки", ситуації, з якими розумна програма не повинна намагатися впоратися. Ці об'єкти доставляються за тим самим механізмом, який використовується для доставки винятків, але вони мають особливе значення сигналів про невиправні ситуації.


6

Я не маю етимологічних досліджень щодо витоків цього, але можу зрозуміти, що використання терміна "Помилка" може бути не точним у всіх ситуаціях; також, як згадується майжеSharepointMaster, краще думати про помилку та виняток, викинуті як відокремлені об'єкти.

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

Я вперше побачив термін "виняток" у посібнику зі зборів 80386. Я пам’ятаю, що коли я побачив, це миттєво виглядало для мене природним. Закликати цю помилку було б невірно, оскільки в Асамблеї немає помилок; просто існують умови, з якими процесор не може впоратися (якщо це помилка - від програміста, користувача або системи - ну, процесор до цього абсолютно агностичний). Я не знаю, чи справді Intel походить з цього терміну чи ні, але, можливо, ...


3

Зазвичай виняток використовується для іменування події, яка є невірною, але її можна відновити, як out_of_rangeвиняток у C ++, який викидається під час доступу до елемента у векторному або масиві, який не існує. Очевидно, що така подія є невірною, але це не повинно означати збоїв у вашій програмі.

З іншого боку, помилки зазвичай використовуються для того, щоб назвати щось, що повинно зірвати все, щось на зразок переповнення стека є прикладом події, яка повинна припинити програму, оскільки програма не може впоратись із нею. Іншими словами: помилка є головною, а виняток - порівняно незначною.


3

Я думаю, що це має більше спільного з "еволюцією" обробки помилок. Якщо мови C / C ++ (до того, як було додано обробку виключень), якщо функція не вдалася, єдиний спосіб сказати це через повернене значення (наприклад, HRESULTу win32). Отже, ти зазвичай вловлюєш вихідні коди кожного виклику функції та робиш перевірку. Такий підхід робить код месіє. І багато разів розробники просто уникатимуть додавання цих чеків із ліні.

З впровадженням обробки винятків розробники мали два варіанти помилок. Тож слово "виняток" було використано для відмежування помилок від помилок "статус виходу". Через деякий час обробка винятків стала популярним способом розповсюдження помилок, оскільки код набагато простіше читати, підтримувати і може бути єдине місце, де ви можете мати логіку обробки помилок.


2

У Python вони названі як ABCError Eg: KeyError, IndexError

http://docs.python.org/library/exceptions.html

Тож я думаю, це залежить від мови, якою ви користуєтесь.


4
Не забувайте VB (класичний, не. Net). On Error Goto було використано. І найдивовижніший винахід усіх часів "On Error Resume Next"
Кіббі

1
У Python помилки - це підмножина винятків. Існують чотири стандартні винятки, які успадковують від Exception, але не успадковують від StandardError: StopIteration, GeneratorExit, KeyboardInterrupt і SystemExit.
Дірк Холсоппл

1

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

Виняток помилки - виняток, який детально описує помилку, тому не все є помилкою, яка є винятком, якщо це має сенс;), наприклад, noneimplemetedexception не повинно бути помилкою, а підкреслити виняток.

http://msdn.microsoft.com/en-us/library/system.exception.aspx


0

У програмах iOS / Mac ми маємо як винятки, так і помилки на одній мові.

Принаймні, у цьому середовищі виняток є "не підлягає відновленню", а помилка - "підлягає відшкодуванню".

Наприклад:

  • якщо у вас масив з 10 елементами, і ви намагаєтеся отримати доступ до елемента в індексі 30 - це буде винятком. Ви помилилися у своєму програмуванні.
  • якщо ви спробуєте завантажити URL-адресу, але немає підключення до Інтернету, цього можна очікувати, і ви повинні подати користувачеві якесь повідомлення.

Винятки, як правило, руйнують вашу програму, тоді як помилки, як правило, повертаються nilта об'єкт помилки (повертається як параметр еталонного методу). Ви можете вилучити винятки за допомогою блоку try / catch / нарешті, але рекомендується ніколи не користуватися цією мовною функцією - якщо ви зможете відновити виняток будь-яким способом, то ви взагалі не повинні кидати виняток (ви повинні повернутись замість цього об'єкт помилки).


2
Ну, це зовсім інше, ніж те, що винятки та помилки призначені для інших розробників тоді!
Тарік

Я думаю, кожна мова є різною. Objective-C / какао - одна з найдавніших мов в активному використанні (приблизно з 1983 року), тому, можливо, це трохи старомодно. Однак, якщо визначення змінюється від однієї спільноти до іншої, важливо це знати.
Абхі Беккерт

0

Помилка є те , що пішло не так у виконанні програми. Часто це вирішується шляхом підняття винятку , але

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

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

Виняток - синтаксичне поняття: це щось у самій програмі, незалежне від очікувань когось щодо того, що має робити ця програма. Рутина або робить, або не викликає винятку, незалежно від того, що хто думає.


0

Винятки та помилки різні.

Винятки - це ситуації, які програма може подолати, наприклад, ви намагаєтесь відкрити файл, а його не існує, тоді як помилки - це ситуації, з якими програма нічого не може зробити, як, наприклад, збій диска або помилка оперативної пам'яті.


0

Збільшення та поводження з винятками - це функції потоку управління, а назва винятку повинна відповідати наміченому використанню. Дизайнер коду та API повинен знайти хороші та послідовні схеми іменування.

Тож відповідь на ваше запитання: це залежить від контексту та перспективи.


0

Винятки складалися як узагальнення помилок. Перша мова програмування , щоб включити механізм виключення був Lisp на початку 1970 - х років. Хороший підсумок у «Шаблоні еволюції мови» Габріеля та Стіла. Винятки (які ще не називались винятками) виникли через необхідність уточнення поведінки програми у разі виникнення помилки. Одна з можливостей - зупинити програму, але це не завжди корисно. У реалізаціях Lisp традиційно був спосіб ввести відладчик з помилкою, але іноді програмісти хотіли включити обробку помилок у свою програму. Тож у 1960-х реалізаціях Lisp з'явився спосіб сказати "зроби це, і якщо станеться помилка, зроби це замість цього". Спочатку помилки походили від примітивних функцій, але програмістам було зручно свідомо запускати помилку, щоб пропустити частину програми та перейти до обробника помилок.

У 1972 році в MacLisp з'явилася сучасна форма обробки винятків у Lisp: throwand catch. Збереження Group Software перераховує багато матеріалу на ранніх реалізаціях Lisp, включаючи The Maclisp Reference Manual Revision 0 Девід Місяця . Примітиви catchі throwзадокументовані в §5.3 с.43.

catchє функцією LISP для здійснення структурованих не локальних виходів. (catch x)оцінює xта повертає свої значення, за винятком випадків, коли під час оцінювання x (throw y)слід оцінювати, catchнегайно повертається yбез додаткової оцінки x.

catchможе також використовуватися з контурним аргументом, не оціненим, який використовується як тег для розмежування вкладених уловів. (…)

throwвикористовується catchяк структурований нелокальний механізм виходу.

(throw x)оцінює xта повертає значення до останнього catch.

(throw x <tag>)xповертає значення назад до останнього, catchпозначеного міткою <tag>або без маркування.

Основна увага приділяється нелокальному контрольному потоку. Це форма гото (тільки вгору гото), яку ще називають стрибком . Метафора полягає в тому, що одна частина програми передає значення для повернення до обробника винятків, а обробник винятків ловить це значення і повертає його.

Більшість мов програмування сьогодні пакують тег та значення у об’єкт винятку та поєднують механізм лову з механізмом обробки.

Винятки - це не обов'язково помилки. Вони є способом виходу з блоку коду та з навколишніх блоків, уникаючи обробника для виключення. Чи вважається така річ «помилкою» в інтуїтивному розумінні суб’єктивно.

Деякі мови розрізняють терміни "помилка" та "виняток". Наприклад, деякі діалекти Lisp мають як throwстворити виняток (потік управління для користувачів, який мав на увазі виконувати не локальний вихід таким чином, що не вказує на те, що щось пішло «не так»), так і signalвикликати помилку (що вказує на те, що щось пішло «не так» і може викликати події налагодження).


-1

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


-1

Помилка - це завжди помилка. Виняток - помилка в поточному контексті. Тобто виняток є залежним від контексту. Прикладом виключення може бути додавання ascii "a" до цілого числа "1". Помилка може бути чимось на зразок використання невизначеного оператора типу "+!" у більшості мов.

Деякі моменти дозволять вам визначити свій вихід із ситуації, якщо це дійсно те, що ви хочете зробити.

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