Pytanie Dlaczego obsługa wyjątków jest zła?


Język Google Go nie ma wyjątków jako wybór projektu, a Linus z Linuksa nazywa bzdury wyjątkami. Czemu?


76
2017-11-15 00:38


pochodzenie


Twórca ZeroMQ pisze o tym, jak myśli, że pisanie go w C ++ było błędem (głównie z powodu obsługi błędów) 250bpm.com/blog:4 - serbaut
Go może nie mieć wyjątków, ale ma "panikę", z której możesz "odzyskać" (podczas gdy odroczone instrukcje są nadal wykonywane) i zapewniają nielokalny przepływ sterowania ... - Kerrek SB
Oto ładny artykuł lighterra.com/papers/exceptionsharmful (Obsługa wyjątków traktowana jako szkodliwa) - masterxilo
Afaici, wyjątki mogą być symulowane w programie Go ze znaczącą tabelą, chociaż ten punkt może być bardziej znaczący dla transpozycji z cukru składniowego niż dla ręcznego wpisywania tablicy. - Shelby Moore III


Odpowiedzi:


Wyjątki sprawiają, że pisanie kodu, w którym zgłaszany wyjątek łamie niezmienniki i pozostawia obiekty w niespójnym stanie, jest naprawdę łatwe. Zasadniczo zmuszają cię do zapamiętania, że ​​większość wyciągniętych przez ciebie stwierdzeń może potencjalnie rzucić i prawidłowo to znieść. Może to być trudne i sprzeczne z intuicją.

Rozważ coś takiego jako prosty przykład:

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

Zakładając FrobManager będzie delete  FrobObject, to wygląda OK, prawda? A może nie ... Wyobraź sobie, że albo FrobManager::HandleFrob() lub operator new zgłasza wyjątek. W tym przykładzie przyrost o m_NumberOfFrobs nie zostanie wycofany. Tak więc każdy, kto używa tej instancji Frobber będzie prawdopodobnie uszkodzony obiekt.

Ten przykład może wydawać się głupi (ok, musiałem się trochę rozprostować, aby go skonstruować :-)), ale na wynos jest to, że jeśli programista nie zawsze myśli o wyjątkach, i upewnia się, że każda permutacja stanu zostanie wyrzucona kiedy pojawiają się rzuty, wpadasz w kłopoty w ten sposób.

Na przykład możesz myśleć o tym jak o muteksach. Wewnątrz sekcji krytycznej polegasz na kilku instrukcjach, aby upewnić się, że struktury danych nie są uszkodzone, a inne wątki nie mogą zobaczyć twoich wartości pośrednich. Jeśli któreś z tych zdań po prostu nie działa, kończy się to w świecie bólu. Teraz zabierz blokady i współbieżność i pomyśl o każdej takiej metodzie. Pomyśl o każdej metodzie jako o transakcji permutacji na stanie obiektu, jeśli tak. Na początku wywołania metody obiekt powinien być w stanie czystym, a na końcu powinien być również czysty. Pomiędzy, zmienna foo może być niezgodne z bar, ale twój kod w końcu to poprawi. Wyjątki oznaczają, że każde z Twoich wypowiedzi może w każdej chwili przerwać. Obowiązek spoczywa na Tobie w każdej indywidualnej metodzie, aby uzyskać to prawo i wycofać, kiedy to się stanie, lub zamówić operacje, aby rzuty nie wpłynęły na stan obiektu. Jeśli popełnisz błąd (i łatwo popełnisz taki błąd), wówczas rozmówca zobaczy twoje wartości pośrednie.

Metody takie jak RAII, które programistów C ++ uwielbiają wymieniać jako ostateczne rozwiązanie tego problemu, stanowią długą drogę, aby temu zapobiec. Ale nie są srebrną kulą. Zapewni to zwolnienie zasobów przy rzucie, ale nie zwalnia z konieczności myślenia o korupcji stanu obiektu, a rozmówcy widzą wartości pośrednie. Więc dla wielu ludzi łatwiej powiedzieć, przez fiat stylu kodowania, bez wyjątków. Jeśli ograniczysz rodzaj kodu, który napiszesz, trudniej będzie wprowadzić te błędy. Jeśli nie, łatwo popełnić błąd.

Całe książki zostały napisane o kodowaniu wyjątków w C ++. Wielu ekspertów popełniło błąd. Jeśli jest naprawdę tak złożony i ma tak wiele niuansów, może to dobry znak, że musisz zignorować tę funkcję. :-)


64
2017-11-15 01:59



Ciekawa odpowiedź, jednak nie odzwierciedla niczego w moim doświadczeniu programistycznym. Sądzę więc, że jest to specyficzne dla kultury (może bardziej problem w Javie lub C ++ niż, powiedzmy, Python) lub specyficzne dla domeny. - ddaa
Wyjątki napisane w zarządzanym języku za pomocą wzoru try-catch-finally nigdy nie powinny pozostawiać nieprawidłowego stanu, jeśli są napisane poprawnie; ponieważ gwarantowany jest ostatecznie blok finally, obiekty mogą być tam przydzielone. Resztę powinny zajmować zmienne wychodzące poza zakres i usuwanie śmieci. - Robert Harvey♦
@ddaa Problem jest zdecydowanie możliwy w Pythonie. Rezultatem jest zazwyczaj trudny do odtworzenia błąd. Być może byłeś wyjątkowo skrupulatny lub szczęśliwy. Ale masz rację, że jest to bardziej problem w C ++, gdzie najczęstszym błędem ze słabej EH jest wyciek pamięci. Próbowałem podkreślić, że przecieki nie są najpoważniejszym problemem. @Robert GC złagodzi wycieki pamięci, ale nie jestem pewien, czy zarządzany kod uwolni cię od błędu programisty. W szczególności, jeśli ktoś nie zwraca uwagi na wyjątkowe bezpieczeństwo, ponieważ nie uważa, że ​​jest to problem w ich języku, nie jest to świetny znak. - asveikau
@lzprgmr tam na pewno są: wyjątki pozwalają radzić sobie z diff. rodzaje błędów w różnicach. miejsca w kodzie. Radzenie sobie z błędem połączenia może wymagać ponownego połączenia, ale nie w środku głęboko zagnieżdżonej funkcji. Chcesz to przekazać menedżerowi połączeń lub coś podobnego. Następnie radzenie sobie z wartościami zwracanymi zmusza do sprawdzania błędów w każdym pojedynczym wywołaniu, a także do ręcznego wywoływania bańki (w przypadku błędu resetowania połączenia np.). Również wartości zwracane są ułożone w zagnieżdżonych połączeniach: func3 może zwracać -1, func2 wywołuje func3, zwraca -2 na swoich błędach, -1 dla func3 itp. - abourget
Głosowałem, ale odwróciłem to, ponieważ jest to powód, dla którego patrzy się na wyjątki. Jednak moim zdaniem prawie każda metoda lub fragment kodu może zawieść. Nie można obsłużyć każdego warunku błędu, wprowadzając dla niego wartość zwracaną. Utracisz informacje o błędzie. Myślenie, że możesz wszystko ładnie zsynchronizować, sprawdzając każde stwierdzenie, a wykonanie czyszczenia prowadzi do bardzo skomplikowanego kodu - złapanie błędu przez wiele instrukcji i wyczyszczenie jednego lub dwóch zasobów, które nie są GC'ed, jest znacznie czystsze. - Maarten Bodewes


Powód, dla którego Go nie ma wyjątków, wyjaśniono w FAQ na temat projektowania języka Go:

Wyjątki to podobna historia. ZA   liczba projektów wyjątków   zostały zaproponowane, ale każdy dodaje   znaczna złożoność języka   i czas działania. Ze względu na swój charakter,   funkcje wyjątków i być może   nawet goroutiny; oni mają   szerokie implikacje. Jest   także obawy o efekt, który oni   miałby na bibliotekach. Oni są,   z definicji wyjątkowe jeszcze   doświadczenie z innymi językami, które   wspierać je, pokazać, że mają głębokie   wpływ na bibliotekę i interfejs   specyfikacja. Byłoby miło   znajdź projekt, który pozwoli im być   naprawdę wyjątkowy bez zachęcania   typowe błędy, które zamieniają się w specjalne   przepływ sterowania, który wymaga każdego   programista do zrekompensowania.

Podobnie jak generyczne, wyjątki pozostają   otwarty problem.

Innymi słowy, nie odkryli jeszcze, jak wspierać wyjątki w Go w sposób, który ich zdaniem jest zadowalający. Nie twierdzą, że wyjątki są złe jako taki;

AKTUALIZACJA - maj 2012

Projektanci Go schodzili teraz z płotu. Ich często zadawane pytania mówią teraz:

Uważamy, że wyjątki sprzęgania ze strukturą kontrolną, jak w idiomu try-catch-finally, skutkują zawiłym kodem. Ma także skłonić programistów do etykietowania zbyt wielu zwykłych błędów, takich jak nieudane otwarcie pliku, jako wyjątkowych.

Go stosuje inne podejście. W przypadku zwykłej obsługi błędów, wielowartościowe deklaracje Go ułatwiają zgłaszanie błędów bez przeciążania zwracanej wartości. Kanoniczny typ błędu w połączeniu z innymi funkcjami Go sprawia, że ​​obsługa błędów jest przyjemna, ale zupełnie inna niż w innych językach.

Go ma również kilka wbudowanych funkcji do sygnalizowania i odzyskiwania z naprawdę wyjątkowych warunków. Mechanizm odzyskiwania jest wykonywany tylko jako część stanu działania, który jest niszczony po błędzie, który jest wystarczający do obsługi katastrofy, ale nie wymaga żadnych dodatkowych struktur kontrolnych, a gdy jest dobrze wykorzystywany, może skutkować czystym kodem obsługi błędów.

Szczegółowe informacje można znaleźć w artykule Defer, Panic i Recover.

Tak więc krótka odpowiedź brzmi, że mogą to zrobić inaczej, stosując zwrot wielowartościowy. (I tak, i tak mają formę obsługi wyjątków.)


... a Linus z Linuksa słynie z wyjątkowych bzdur.

Jeśli chcesz wiedzieć, dlaczego Linus sądzi, że wyjątki są bzdurne, najlepiej jest poszukać jego pism na ten temat. Jedyne, co do tej pory wyśledziłem, to ten cytat, który jest osadzony w kilka e-maili w C ++:

"Cała obsługa wyjątków w C ++ jest zasadniczo zepsuta. Jest szczególnie uszkodzona w przypadku jądra."

Zwróć uwagę, że on mówi w szczególności o wyjątkach C ++, a nie o wyjątkach w ogóle. (Oraz wyjątki C ++ zrobić najwyraźniej mają pewne problemy, które sprawiają, że są one trudne do prawidłowego użycia.)

Mój wniosek jest taki, że Linus w ogóle nie nazwał wyjątków (ogólnie) "gównem"!


47
2017-11-15 02:43



Nienawidzę tego, gdy ukrywają informacje, umieszczając je w FAQ. :) - brian d foy
Zauważ, że Linus uruchamia ten e-mail z "C ++ jest okropnym językiem". i nadal donosi o tym, jak bardzo nienawidzi zarówno C ++, jak i ludzi, którzy decydują się na programowanie w nim. W związku z tym nie sądzę, jego opinia na temat wyjątków C ++ można uznać za wiarygodne, biorąc pod uwagę jego nieco stronniczy opinii na temat C ++. - Pharap
@ Hi-Angel - Jako cytowany przeze mnie tekst: "W przypadku zwykłej obsługi błędów, wielowartościowe deklaracje Go ułatwiają zgłaszanie błędu bez przeciążania zwracanej wartości.". Tak to jest powiązane. Tak czy inaczej, powołuję się na racjonalność projektantów Go. Jeśli chcesz się spierać, argumentuj >> >>. - Stephen C
@ Hi-Angel - Nie napisałem tych akapitów. Ja tylko zacytowałem je. Jeśli masz z nimi problem, prawdopodobnie powinieneś podjąć to z autorami. Teoretycznie mogłem podać tutorial w języku Go jako kontekst. Ale szczerze mówiąc, ludzie, którzy nie rozumieją terminologii Go mogą odwiedzić stronę Go, aby dowiedzieć się, co to wszystko znaczy. - Stephen C
"... powoduje zawiłe kodowanie" Dawno temu napisałem program C z wieloma operacjami łańcuchowymi. Każda metoda to alokacja pamięci, a następnie sprawdzenie, czy alokacja zakończyła się sukcesem. Wyglądało na to, że większość kodu to tylko sprawdzanie przydziałów. Czy to nie jest zawiłe? C ++ z wyjątkami było dla mnie wielką pomocą. - robsosno


Wyjątki nie są złe same w sobie, ale jeśli wiesz, że będą się dziać dużo, mogą być kosztowne pod względem wydajności.

Zasadą jest, że wyjątki powinny oznaczać wyjątkowe warunki i nie należy ich używać do kontroli przepływu programu.


28
2017-11-15 00:41



@Robert: "nie powinieneś ich używać do kontroli przepływu programu", nie myślałem o tym w ten sposób, nowa perspektywa dla mnie: P +1 - o.k.w
To naprawdę zależy od języka. Trudno uniknąć wyjątków, jeśli na przykład programujesz w Javie. - Charles Salvia
@Charles: Myślę, że chodzi o to, że wyjątki są odpowiednie w sytuacjach, które wskazują na błąd, źle skonfigurowany system lub nieuzasadnione dane wejściowe. Większości wyjątków biblioteki Java można uniknąć w kodzie "normalnego przepływu pracy". - Artelius
nie muszą wiele kosztować. na przykład możesz zaimplementować "próbę", która kosztuje zero czasu wykonania, i "wyrzuć" wyszukuj obsługę wyjątków w tabeli na podstawie adresów wywołujących, które widzi na stosie ... Powiedziałbym, że największe powody, aby nie wyjątki nie są wcale związane z wydajnością. - asveikau
Przeformułowano; to pytanie wyraźnie wskazuje na ogólne zastosowanie wyjątków lub niestosowanie wyjątków (są to bzdury lub nawet nie są w języku). Twoja odpowiedź pokazuje tylko, dlaczego wyjątki są złe dla wydajności, gdy są używane do kontroli programu. - Maarten Bodewes


Nie zgadzam się z "wyrzucaniem wyjątków w wyjątkowej sytuacji". Chociaż generalnie jest to prawda, to wprowadza w błąd. Wyjątki są dla błąd warunki (awarie wykonania).

Bez względu na używany język, wybierz kopię Wytyczne dotyczące projektowania ram: Konwencje, idiomy i wzorce dla bibliotek wielokrotnego użytku .NET (wydanie drugie). Rozdział o rzucaniu wyjątków jest bez rówieśnika. Niektóre cytaty z pierwszej edycji (drugie w mojej pracy):

  • NIE RÓB zwróć kody błędów.
  • Kody błędów mogą być łatwo ignorowane i często są.
  • Wyjątki są głównym sposobem zgłaszania błędów w frameworkach.
  • Dobrą zasadą jest to, że jeśli metoda nie działa tak, jak sugeruje jej nazwa, należy ją uznać za awarię na poziomie metody, co powoduje wyjątek.
  • NIE RÓB używać wyjątków do normalnego przepływu sterowania, jeśli to możliwe.

Istnieją strony uwag na temat zalet wyjątków (spójność interfejsu API, wybór lokalizacji kodu obsługi błędów, poprawiona niezawodność itd.) Istnieje sekcja dotycząca wydajności, która zawiera kilka wzorców (Tester-Doer, Try-Parse).

Wyjątki i obsługa wyjątków nie zły. Jak każda inna funkcja, mogą być niewłaściwie używane.


23
2017-11-15 03:41



Muszę się z tym nie zgodzić. Nie jestem przeciwny wyjątkom, a ta książka jest koniecznością, jednak jest stronnicza w kierunku rozwoju .NET i C #. - Ion Todirel
Wiem, że to jest starożytny, po prostu chciałem skomentować, że wydaje się, że będzie ogólny spór stylu między typem .NET a typem * nix. Wszystkie biblioteki, których używałem jako deweloperów Linuksa, używają kodów powrotnych i * przewodników w stylu nix, które czytałem (jak moja firma i Google na przykład) po prostu powiedz "nie robimy wyjątków". Pomyśl tylko, że to interesujące. - jarvisteve
Ramy powinny traktować wyjątki inaczej niż aplikacje użytkowników końcowych. Ramy nie mają sposobu na poradzenie sobie z błędami innymi niż wyrzucanie wyjątków, robią to aplikacje konsumenckie. - Mr D


Z punktu widzenia golanga, domyślam się, że brak obsługi wyjątków sprawia, że ​​proces kompilowania jest prosty i bezpieczny.

Z perspektywy Linusa rozumiem, że kod jądra dotyczy WSZYSTKICH przypadków narożnych. Więc rozsądnie jest odmówić wyjątków.

Wyjątki mają sens w kodzie, w którym można upuścić bieżące zadanie na podłogę, a wspólny kod sprawy ma większe znaczenie niż obsługa błędów. Ale wymagają generowania kodu z kompilatora.

Na przykład są one dobre w większości wysokopoziomowych, skierowanych do użytkowników kodów, takich jak kod aplikacji internetowej i komputerowej.


11
2017-11-15 00:53



Ale to, co jest prawdą w kodzie jądra, odnosi się również do długo działających natywnych procesów serwera. - Lothar


Typowe argumenty są takie, że nie ma sposobu, aby stwierdzić, jakie wyjątki wyjdą z konkretnego fragmentu kodu (w zależności od języka) i że są zbyt podobne gotos, co utrudnia psychiczne śledzenie wykonania.

http://www.joelonsoftware.com/items/2003/10/13.html

W tej kwestii zdecydowanie nie ma zgody. Powiedziałbym, że z punktu widzenia twardego programisty C, takiego jak Linus, wyjątki są zdecydowanie złym pomysłem. Typowy programista Java znajduje się jednak w zupełnie innej sytuacji.


9
2017-11-15 00:43



Kod C ma pewne wyjątki, tylko w inny sposób. Musisz zawijać każde wywołanie do nietrywialnej funkcji w ifs, co sprawia, że ​​używanie tego języka to ból głowy! - RCIX
Jest też setjmp/longjmp rzeczy, które są dość złe. - Tim Sylvester
Czy naprawdę chcesz skorzystać z rady człowieka, który ceni programistów Duct Tape i który nie wierzy, że testy jednostkowe są konieczne? joelonsoftware.com/items/2009/09/23.html - TrueWill
Jest to klasyczny błąd (lub oszukiwanie) w dyskusji, w której argumenty na ten temat zastępowane są odniesieniami do osobowości. Zazwyczaj jest to oznaka degenerującej się dyskusji. - Petr Gladkikh
@PetrGladkikh Dyskusja Rozpoczęty z OP odnoszącym się do opinii Linusa ... że oszustwo jest znane jako błędne odwoływanie się do władzy. Dyskusja może tylko stamtąd pod górę i nie jest to "oszustwo", aby odpowiedzieć na pytanie, dlaczego Linus nie lubi wyjątków, odwołując się do jego osobowości. - Jim Balter


Wyjątki same w sobie nie są "złe", jest to sposób, w jaki czasami obsługiwane są wyjątki, które zwykle są złe. Istnieje kilka wytycznych, które można zastosować podczas rozwiązywania wyjątków, aby złagodzić niektóre z tych problemów. Niektóre z nich obejmują (ale z pewnością nie są ograniczone do):

  1. Nie używaj wyjątków do sterowania przepływem programu - tzn. Nie polegaj na instrukcjach "catch", aby zmienić przepływ logiki. Nie tylko powoduje to ukrywanie różnych szczegółów wokół logiki, ale także może prowadzić do niskiej wydajności.
  2. Nie wyrzucaj wyjątków z funkcji, gdy zwrócony "status" miałby więcej sensu - w wyjątkowych sytuacjach można zgłaszać wyjątki. Tworzenie wyjątków jest kosztowną operacją wymagającą dużej wydajności. Na przykład, jeśli wywołasz metodę otwierania pliku, a ten plik nie istnieje, wyrzuć wyjątek "FileNotFound". Jeśli wywołasz metodę, która określa, czy konto klienta istnieje, zwróć wartość logiczną, nie zwracaj wyjątku "CustomerNotFound".
  3. Podczas określania, czy należy obsłużyć wyjątek, nie używaj klauzuli "try ... catch", chyba że możesz zrobić coś użytecznego z wyjątkiem. Jeśli nie jesteś w stanie obsłużyć wyjątku, po prostu pozwól mu spaprać w stos wywoławczy. W przeciwnym razie wyjątki mogą zostać "połknięte" przez handler'a, a szczegóły zostaną utracone (chyba że ponownie zgłoszony zostanie wyjątek).

9
2017-11-15 02:22



Powrót statusu jest trudny. Widziałem zbyt wiele kodu, który ma metodę GetCustomer zwracającą jednostkę Customer w przypadku sukcesu lub wartość zerową w przypadku niepowodzenia. W wielu przypadkach kod wywołujący nigdy nie sprawdzał wyniku, ale natychmiast uzyskał dostęp do klienta. To działało przez większość czasu ... - TrueWill
Ale jeśli GetCustomer zgłasza wyjątek zamiast zwracania wartości null, kod klienta nadal musi obsługiwać wyjątek. Niezależnie od tego, czy chodzi o sprawdzenie wartości null, czy też o obsługę wyjątków, odpowiedzialność spoczywa na kodzie klienta - jeśli nie robi to, co jest właściwe, to w jakiś sposób prędzej czy później coś eksploduje. - Chris
@TrueWill Języki obsługujące szablony / generics rozwiązują to przez zwracanie Option<T> zamiast null dzisiaj. Właśnie został wprowadzony na przykład w Javie 8, biorąc pod uwagę wskazówki od Guava (i innych). - Maarten Bodewes
@owlstead Yep. Uwielbiam może monadę. To dobry sposób, aby przejść, jeśli twój język je obsługuje i oferuje dopasowywanie wzorców. - TrueWill
@owlstead Znowu, to, co powiedział Chris, nadal jest do tego mocne - użytkownik musi pamiętać, aby wywołać funkcję .orElse (defaultObject) lub dowolny idiom, o którym zadecydował dany język. Pod koniec dnia ostatecznie chodzi o programistów, a nie o sposób obsługi błędów. - Pharap


Wyjątki nie są złe. Pasują do modelu CII w języku C ++, który jest najbardziej eleganckim elementem C ++. Jeśli masz już pakiet kodu, który nie jest bezpieczny w wyjątkach, w tym kontekście są one złe. Jeśli piszesz naprawdę niskopoziomowe oprogramowanie, takie jak system operacyjny Linux, to są one złe. Jeśli lubisz zaśmiecać kod za pomocą kilku sprawdzeń zwracających błędy, to nie są pomocne. Jeśli nie masz planu kontroli zasobów podczas zgłaszania wyjątku (który zapewnia destruktor C ++), to są one złe.


7
2017-11-15 00:49



RAII jest przydatne nawet bez wyjątków. - Mark Ransom
jednak wyjątki nie są użyteczne bez RAII (lub innego automatycznego zarządzania zasobami). - Greg Rogers
+1 za wskazanie sytuacji, w których wyjątki nie są właściwe i że wyjątki nie są z natury złe. - Pharap


Wielkim przypadkiem użycia wyjątków jest ...

Powiedzmy, że jesteś na projekcie i każdy kontroler (około 20 różnych głównych) rozszerza pojedynczy kontroler nadklasy za pomocą metody akcji. Następnie każdy kontroler robi kilka rzeczy różniących się od siebie obiektami wywołującymi B, C, D w jednym przypadku i F, G, D w innym przypadku. Wyjątki przychodzą tu na ratunek w wielu przypadkach, gdzie było mnóstwo kodów powrotu i KAŻDY kontroler obsługiwał to inaczej. Uderzyłem cały ten kod, wyrzuciłem odpowiedni wyjątek z "D", złapałem go w sposób działania kontrolera nadklasy, a teraz wszystkie nasze kontrolery są spójne. Poprzednio D zwracał wartość null dla MULTIPLE różnych przypadków błędów, które chcemy przekazać użytkownikowi końcowemu, ale nie mogliśmy i nie chciałem zamienić StreamResponse w nieprzyjemny obiekt ErrorOrStreamResponse (mieszanie struktury danych z błędami w mojej opinii jest nieprzyjemny zapach i widzę, że wiele kodu zwraca "Strumień" lub inny rodzaj encji z wbudowanym w nim informacją o błędzie (powinna to być funkcja zwracająca strukturę sukcesu LUB strukturę błędu, którą mogę zrobić z wyjątkami a kodami powrotu ) ... chociaż sposób wielokrotnego odpowiadania C # jest czymś, co czasem rozważam, chociaż w wielu przypadkach wyjątek może pomijać wiele warstw (warstw, których nie potrzebuję czyścić zasobów na obu).

tak, musimy martwić się o każdy poziom i wszelkie czyszczenie / wycieki zasobów, ale generalnie żaden z naszych kontrolerów nie miał żadnych zasobów do czyszczenia po.

dzięki Bogu mieliśmy wyjątki lub byłbym w wielkim refaktorze i zmarnowałem zbyt dużo czasu na coś, co powinno być prostym problemem programistycznym.


3
2017-07-03 19:38



+1 Łatwo jeden z najlepszych argumentów za używanie wyjątków, które przeczytałem. Mógł użyć bardziej szczegółowych przykładów (tj. Diagram UML, jakiś pseudokod lub jakiś rzeczywisty kod), ale punkt dotyczący robienia podklas konsekwentnie działa jest dobry. Również fakt, że twoje dowody są niepotwierdzone pokazuje, że wyjątki są przydatne w rzeczywistych sytuacjach, a użyteczność jest głównym celem każdej funkcji językowej. - Pharap
jako dodatek, jeśli jesteś w scala, możesz zamiast tego zwrócić próbę [ResponseType], która reprezentuje wyjątek lub faktyczną odpowiedź. Możesz następnie stosować ten sam wzorzec, którego nie rozumiem powyżej, bez faktycznych wyjątków, innych niż te, w które zostały wprowadzone. Wtedy to jest jak każda metoda, którą zwracasz typy odpowiedzi 1 + n, które moim zdaniem są potrzebne. My jednak w scala zwrócimy Future [odpowiedź], która działa podobnie do Try, ale może pomóc w bardziej asynchronicznym programowaniu. - Dean Hiller