अपवाद को संभालना बुरा क्यों है?


90

Google की गो भाषा में डिज़ाइन पसंद के रूप में कोई अपवाद नहीं है, और लिनक्स प्रसिद्धि के लिनस ने अपवादों को बकवास कहा है। क्यों?


2
ZeroMQ के निर्माता लिखते हैं कि वह कैसे सोचते हैं कि इसे C ++ में लिखना एक गलती थी (ज्यादातर त्रुटि से निपटने के कारण) 250bpm.com/blog:4
serbaut

गो के पास अपवाद नहीं हो सकते हैं, लेकिन इसमें "पैनिक" है जिसे आप "पुनर्प्राप्त" कर सकते हैं (जबकि आस्थगित कथनों को अभी भी निष्पादित किया गया है) और यह गैर-स्थानीय नियंत्रण प्रवाह प्रदान करता है ...
केरेक एसबी


अफ़ीक्स, अपवादों को महत्वपूर्ण बॉयलरप्लेट के साथ गो में सिम्युलेट किया जा सकता है , हालांकि यह बिंदु मैन्युअल रूप से बॉयलरप्लेट लिखने के बजाय एक सिंटैक्स चीनी से ट्रांसप्लिंग के लिए अधिक सार्थक हो सकता है।
शेल्बी मूर तृतीय

जवाबों:


82

अपवादों को कोड लिखना वास्तव में आसान होता है, जहां एक अपवाद को फेंक दिया जाता है, जो आक्रमणकारियों को तोड़ देगा और वस्तुओं को असंगत स्थिति में छोड़ देगा। वे अनिवार्य रूप से आपको यह याद रखने के लिए मजबूर करते हैं कि आपके द्वारा दिया गया प्रत्येक कथन संभावित रूप से फेंक सकता है, और सही ढंग से संभाल सकता है। ऐसा करना मुश्किल और जवाबी हो सकता है।

एक साधारण उदाहरण के रूप में इस तरह से कुछ पर विचार करें:

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

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

FrobManagerवसीयत deleteको मानते हुए FrobObject, यह ठीक लगता है, है ना? या हो सकता है नहीं ... तो कल्पना कीजिए कि यदि या तो FrobManager::HandleFrob()या operator newएक अपवाद फेंकता है। इस उदाहरण में, वेतन वृद्धि m_NumberOfFrobsवापस नहीं मिलती है। इस प्रकार, इस उदाहरण का उपयोग Frobberकरने वाले के पास संभवतः दूषित वस्तु होने वाली है।

यह उदाहरण बेवकूफी भरा लग सकता है (ठीक है, मुझे एक निर्माण के लिए खुद को थोड़ा लंबा करना पड़ा), लेकिन, टेकअवे यह है कि अगर कोई प्रोग्रामर लगातार अपवादों के बारे में नहीं सोच रहा है, और यह सुनिश्चित कर रहा है कि राज्य के प्रत्येक क्रमांकन को लुढ़का हुआ है। वापस जब भी फेंकता है, आप इस तरह से मुसीबत में पड़ जाते हैं।

एक उदाहरण के रूप में, आप इसके बारे में सोच सकते हैं जैसे आप म्यूटेक्स के बारे में सोचते हैं। एक महत्वपूर्ण खंड के अंदर, आप यह सुनिश्चित करने के लिए कई कथनों पर भरोसा करते हैं कि डेटा संरचनाएँ दूषित नहीं हैं और अन्य सूत्र आपके मध्यवर्ती मूल्यों को नहीं देख सकते हैं। यदि उन बयानों में से कोई भी बस अनियमित रूप से नहीं चलता है, तो आप दर्द की दुनिया में समाप्त हो जाते हैं। अब ताले और संगति को हटा दें, और उस तरह से प्रत्येक विधि के बारे में सोचें। प्रत्येक विधि को वस्तु स्थिति पर क्रमपरिवर्तन के लेन-देन के रूप में सोचें, यदि आप करेंगे। आपके विधि कॉल के प्रारंभ में, ऑब्जेक्ट को साफ स्थिति होना चाहिए, और अंत में एक साफ राज्य भी होना चाहिए। बीच में, चर के fooसाथ असंगत हो सकता हैbar, लेकिन आपका कोड अंततः उसे ठीक कर देगा। अपवादों का क्या मतलब है कि आपका कोई भी कथन किसी भी समय आपको बाधित कर सकता है। यह प्रत्येक अधिकार विधि में आप पर है कि यह सही हो जाए और जब ऐसा होता है तो वापस रोल करें, या अपने संचालन का आदेश दें ताकि फेंकता वस्तु स्थिति को प्रभावित न करे। यदि आपको यह गलत लगता है (और इस तरह की गलती करना आसान है), तो कॉलर आपके मध्यवर्ती मूल्यों को देखकर समाप्त हो जाता है।

RAII जैसी विधियाँ, जिन्हें C ++ प्रोग्रामर इस समस्या के अंतिम समाधान के रूप में उल्लेख करना पसंद करते हैं, इस से बचाव के लिए एक लंबा रास्ता तय करते हैं। लेकिन वे चांदी की गोली नहीं हैं। यह सुनिश्चित करेगा कि आप संसाधनों को एक थ्रो पर जारी करेंगे, लेकिन आपको वस्तु स्थिति के भ्रष्टाचार और मध्यवर्ती मूल्यों को देखने वाले कॉलर्स के बारे में सोचने से मुक्त नहीं करते हैं। इसलिए, बहुत से लोगों के लिए, कोडिंग शैली के अनुसार, कोई अपवाद नहीं है , यह कहना आसान है । यदि आप अपने द्वारा लिखे गए कोड को प्रतिबंधित करते हैं, तो इन बगों को लागू करना कठिन है। यदि आप नहीं करते हैं, तो गलती करना काफी आसान है।

C ++ में अपवाद सुरक्षित कोडिंग के बारे में पूरी किताबें लिखी गई हैं। बहुत सारे विशेषज्ञों ने इसे गलत माना है। यदि यह वास्तव में जटिल है और इसमें बहुत सारी बारीकियाँ हैं, तो शायद यह एक अच्छा संकेत है कि आपको उस सुविधा को अनदेखा करने की आवश्यकता है। :-)


9
दिलचस्प जवाब, हालांकि यह मेरे प्रोग्रामिंग अनुभव में कुछ भी प्रतिबिंबित नहीं करता है। तो मुझे लगता है कि यह या तो संस्कृति-विशिष्ट है (शायद जावा या सी ++ में समस्या, कहना, अजगर) या डोमेन-विशिष्ट।
डीडीए

42
एक कोशिश-कैच-अंततः पैटर्न का उपयोग करके प्रबंधित भाषा में लिखे गए अपवादों को कभी भी अमान्य स्थिति नहीं छोड़नी चाहिए यदि वे ठीक से लिखे गए हों; चूंकि अंत में ब्लॉक निष्पादित होने की गारंटी है, इसलिए वस्तुओं को वहां से हटा दिया जा सकता है। बाकी का ध्यान दायरे और कचरा संग्रह से बाहर जाने वाले चरों द्वारा लिया जाना चाहिए।
रॉबर्ट हार्वे

7
@ डीडीए मुद्दा निश्चित रूप से पायथन में संभव है। परिणाम आमतौर पर बग को पुन: पेश करने के लिए मुश्किल है। शायद आप विशेष रूप से सावधानीपूर्वक या भाग्यशाली रहे हैं। लेकिन फिर, आप सही हैं कि यह C ++ में एक समस्या है, जहां खराब ईएच से सबसे आम बग एक मेमोरी लीक है। मैंने जोर देकर कहा कि लीक सबसे गंभीर समस्या नहीं है। @Robert GC स्मृति लीक को कम करेगा, लेकिन मुझे यकीन नहीं है कि प्रबंधित कोड आपको प्रोग्रामर त्रुटि से मुक्त कर देगा। विशेष रूप से अगर कोई अपवाद सुरक्षा पर ध्यान नहीं दे रहा है क्योंकि उन्हें नहीं लगता कि यह उनकी भाषा में कोई समस्या है, तो यह एक अच्छा संकेत नहीं है।
asikikau

4
@lzprgmr वहाँ निश्चित रूप से कर रहे हैं: अपवाद आप अंतर से निपटने के लिए अनुमति देते हैं। विभिन्न प्रकार की त्रुटियां। कोड में स्थान। कनेक्शन की त्रुटि से निपटने के लिए एक सामंजस्य की आवश्यकता हो सकती है, लेकिन एक गहरी नेस्टेड फ़ंक्शन के बीच में नहीं। आप बबल को कनेक्शन प्रबंधक या कुछ और करना चाहते हैं। फिर रिटर्न मान के साथ काम करना आपको प्रत्येक एकल कॉल पर त्रुटियों की जांच करने के लिए मजबूर करता है, और मैन्युअल रूप से बबल (पूर्व के लिए एक कनेक्शन त्रुटि के मामले में) बुलबुला। साथ ही, नेस्टेड कॉल में स्टैक वैल्यू वापस आ जाती है: func3 -1 पर वापस आ सकता है, func2 कॉल func3, रिटर्न -2 अपनी त्रुटियों पर, -1 फंक 3 के लिए, इत्यादि ..
abourget

4
मैं नीचे मतदान कर रहा था, लेकिन मैंने इसका उलटा किया क्योंकि यह एक कारण है कि अपवादों को कम करके देखा जाता है। हालांकि मेरी राय में, लगभग किसी भी विधि या कोड का टुकड़ा विफल हो सकता है। आप इसके लिए रिटर्न वैल्यू शुरू करके प्रत्येक त्रुटि स्थिति को संभाल नहीं सकते। आप त्रुटि के बारे में जानकारी को ढीला कर देंगे। यह सोचते हुए कि आप प्रत्येक वस्तु को प्रत्येक कथन की जाँच करके और सफाई करके सब कुछ अच्छी तरह से समन्वयित रख सकते हैं, बहुत जटिल कोड की ओर जाता है - कई बयानों में त्रुटि पकड़ना और एक या दो संसाधनों को साफ करना जो GC'ed नहीं हैं, बहुत साफ है।
मार्टन बॉड्यूस

50

गो भाषा के डिज़ाइन में अपवाद नहीं होने का कारण बताया गया है:

अपवाद एक ऐसी ही कहानी है। अपवादों के लिए कई डिजाइन प्रस्तावित किए गए हैं, लेकिन प्रत्येक भाषा और रन-टाइम के लिए महत्वपूर्ण जटिलता जोड़ता है। उनके स्वभाव से, अपवाद कार्य और शायद गोरोइटिन भी; उनके व्यापक प्रभाव हैं। पुस्तकालयों पर उनके प्रभाव के बारे में भी चिंता है। वे परिभाषा के अनुसार, अन्य भाषाओं के साथ असाधारण अभी तक का अनुभव है जो उनका समर्थन करते हैं जो दिखाते हैं कि वे पुस्तकालय और इंटरफ़ेस विनिर्देश पर गहरा प्रभाव डालते हैं। ऐसा डिज़ाइन ढूंढना अच्छा होगा जो उन्हें विशेष नियंत्रण प्रवाह में बदलने के लिए आम त्रुटियों को प्रोत्साहित किए बिना वास्तव में असाधारण होने की अनुमति देता है जिसकी क्षतिपूर्ति करने के लिए प्रत्येक प्रोग्रामर की आवश्यकता होती है।

जेनेरिक की तरह, अपवाद एक खुला मुद्दा है।

दूसरे शब्दों में, उन्होंने अभी तक यह पता नहीं लगाया है कि गो को अपवाद के रूप में कैसे समर्थन दिया जाए, जो उन्हें लगता है कि संतोषजनक है। वे यह नहीं कह रहे हैं कि अपवाद प्रति खराब हैं ;

अद्यतन - मई २०१२

गो डिजाइनर अब बंद बाड़ पर चढ़ गए हैं। उनके FAQ अब यह कहते हैं:

हम मानते हैं कि एक नियंत्रण संरचना के लिए युग्मन अपवाद, जैसा कि ट्राइ-कैच-आखिर मुहावरे में है, परिणामी कोड में। यह प्रोग्रामर को बहुत सी साधारण त्रुटियों को लेबल करने के लिए प्रोत्साहित करने के लिए भी प्रेरित करता है, जैसे कि एक फ़ाइल को खोलने में विफल होना, असाधारण के रूप में।

गो एक अलग दृष्टिकोण लेता है। सादे त्रुटि हैंडलिंग के लिए, गो के बहु-मूल्य रिटर्न रिटर्न मूल्य को ओवरलोड किए बिना एक त्रुटि की रिपोर्ट करना आसान बनाते हैं। गो की अन्य विशेषताओं के साथ युग्मित एक कैनोनिकल त्रुटि प्रकार, त्रुटि को अन्य भाषाओं में सुखद लेकिन काफी अलग बनाता है।

गो में कुछ अंतर्निहित कार्यों को संकेत देने और वास्तव में असाधारण स्थितियों से उबरने के लिए भी है। पुनर्प्राप्ति तंत्र को एक फ़ंक्शन के राज्य के एक भाग के रूप में केवल एक त्रुटि के बाद फाड़ दिया जाता है, जो तबाही को संभालने के लिए पर्याप्त है, लेकिन इसके लिए कोई अतिरिक्त नियंत्रण संरचनाओं की आवश्यकता नहीं होती है और जब अच्छी तरह से उपयोग किया जाता है, तो स्वच्छ त्रुटि-हैंडलिंग कोड हो सकता है।

जानकारी के लिए Defer, Panic और Recover लेख देखें।

तो संक्षिप्त उत्तर यह है कि वे बहु-मूल्य वापसी का उपयोग करके इसे अलग तरीके से कर सकते हैं। (और उनके पास वैसे भी अपवाद रूप से निपटने का एक तरीका है)


... और लिनक्स प्रसिद्धि के लिनस ने अपवाद बकवास कहा है।

यदि आप यह जानना चाहते हैं कि लिनुस अपवाद क्यों सोचते हैं, तो यह बकवास है, सबसे अच्छी बात यह है कि इस विषय पर उनके लेखन की तलाश करें। केवल एक चीज जो मैंने अभी तक ट्रैक की है, वह यह उद्धरण है जो C ++ पर ईमेल के एक जोड़े में एम्बेडेड है :

"पूरे सी ++ अपवाद को संभालने वाली चीज़ मौलिक रूप से टूटी हुई है। यह विशेष रूप से गुठली के लिए टूटी हुई है।"

आप ध्यान दें कि वह विशेष रूप से C ++ अपवादों के बारे में बात कर रहा है, और सामान्य रूप से अपवाद नहीं। (और सी ++ अपवाद करते हैं जाहिरा तौर पर कुछ मुद्दों है कि उन्हें मुश्किल सही ढंग से उपयोग करने के लिए बनाते हैं।)

मेरा निष्कर्ष यह है कि लिनस ने अपवादों को नहीं बुलाया है (सामान्य रूप से) "बकवास" बिल्कुल नहीं!


30
मैं इसे नफरत करता हूं जब वे जानकारी को FAQ में डालकर छिपाते हैं। :)
brian d foy

7
ध्यान दें कि लिनस उस ईमेल को "C ++ के साथ एक भयानक भाषा है" शुरू करता है। और सी + + और उन लोगों से नफरत करता है जो उसमें प्रोग्राम करने के लिए चुनते हैं। नतीजतन मुझे नहीं लगता कि C ++ के अपवादों के बारे में उनकी राय को C ++ के प्रति उनकी कुछ पक्षपाती राय को देखते हुए विश्वसनीय माना जा सकता है।
चरण

1
@ हाय-एंजेल - जैसा कि मैंने उद्धृत किया गया पाठ कहता है: "सादे त्रुटि से निपटने के लिए, गो के बहु-मूल्य रिटर्न रिटर्न मूल्य को ओवरलोड किए बिना एक त्रुटि की रिपोर्ट करना आसान बनाते हैं।" । यह इसी तरह से संबंधित है। किसी भी तरह से, मैं गो डिजाइनरों के तर्क को उद्धृत कर रहा हूं। यदि आप बहस करना चाहते हैं, तो उनके साथ बहस करें >> <<।
स्टीफन सी।

1
@ हाय-एंजेल - मैंने उन पैराग्राफ को नहीं लिखा। मैंने केवल उन्हें उद्धृत किया। यदि आपको उनके साथ कोई समस्या है, तो आपको संभवतः इसे लेखकों के साथ उठाना चाहिए। सिद्धांत रूप में, मैं संदर्भ के रूप में गो भाषा पर एक ट्यूटोरियल प्रदान कर सकता था। लेकिन स्पष्ट रूप से, जो लोग गो शब्दावली को नहीं समझते हैं, वे गो वेबसाइट पर जा सकते हैं ताकि यह पता लगाया जा सके कि इसका क्या मतलब है।
स्टीफन सी।

1
".. परिणामी कोड में" लंबे समय पहले मैंने कई स्ट्रिंग ऑपरेशन के साथ सी प्रोग्राम लिखा है। हर विधि को आबंटन मेमोरी थी और फिर जाँच की गई कि क्या आवंटन succesfull था। ऐसा प्रतीत हुआ कि अधिकांश कोड केवल आवंटन की जाँच कर रहे थे। क्या यह दोषपूर्ण नहीं है? अपवादों के साथ C ++ मेरे लिए एक बड़ा बचाव था।
रोजबोसो

29

अपवाद प्रति से खराब नहीं हैं, लेकिन अगर आप जानते हैं कि वे बहुत कुछ होने जा रहे हैं, तो वे प्रदर्शन के मामले में महंगे हो सकते हैं।

अंगूठे का नियम यह है कि अपवादों को असाधारण परिस्थितियों को चिह्नित करना चाहिए, और यह कि आपको उन्हें कार्यक्रम के प्रवाह के नियंत्रण के लिए उपयोग नहीं करना चाहिए।


9
@ रॉबर्ट: "आपको उन्हें प्रोग्राम फ्लो के नियंत्रण के लिए उपयोग नहीं करना चाहिए", मैंने इसके बारे में इस तरह से नहीं सोचा है, मेरे लिए नया दृष्टिकोण: P +1
okw 15'09

2
यह वास्तव में भाषा पर भी निर्भर करता है। यदि आप उदाहरण के लिए जावा में प्रोग्रामिंग कर रहे हैं तो अपवादों से बचना मुश्किल है।
चार्ल्स साल्विया

2
@Charles: मुझे लगता है कि बिंदु यह है कि अपवाद उन स्थितियों में उपयुक्त हैं जो बग, गलत प्रणाली या अनुचित इनपुट का संकेत देते हैं। अधिकांश जावा लाइब्रेरी अपवादों को "सामान्य वर्कफ़्लो" कोड में टाला जा सकता है।
आर्टिलियस

6
उन्हें ज्यादा खर्च नहीं करना पड़ेगा। उदाहरण के लिए, आप एक "कोशिश" को लागू कर सकते हैं जिसमें शून्य निष्पादन समय खर्च होता है, और एक तालिका में अपवाद हैंडलर देखने के लिए "फेंक" होता है जो स्टैक पर देखे गए पते के आधार पर होता है ... मैं कहूंगा कि सबसे बड़े कारण नहीं उपयोग अपवाद प्रदर्शन से संबंधित नहीं हैं।
अश्वेकाऊ

पुनः निर्मित; यह प्रश्न स्पष्ट रूप से अपवादों का उपयोग करने पर स्पष्ट रूप से संकेत देता है, या अपवादों का बिल्कुल भी उपयोग नहीं करता है (वे बकवास हैं या भाषा में भी नहीं हैं)। आपका उत्तर केवल यह बताता है कि जब कार्यक्रम नियंत्रण प्रवाह के लिए उपयोग किया जाता है तो अपवाद प्रदर्शन के लिए खराब क्यों होते हैं।
मार्टेन बॉड्यूस

26

मैं "केवल असाधारण स्थिति में अपवादों को फेंकने" से असहमत हूं। जबकि आम तौर पर सच है, यह भ्रामक है। अपवाद त्रुटि स्थितियों (निष्पादन विफलताओं) के लिए हैं।

आपके द्वारा उपयोग की जाने वाली भाषा के बावजूद, फ्रेमवर्क डिज़ाइन दिशानिर्देशों की एक प्रति चुनें : कन्वेंशन, मुहावरे, और पुन: प्रयोज्य .NET लाइब्रेरीज़ (2 डी संस्करण) के लिए पैटर्न। अपवाद फेंकने का अध्याय बिना सहकर्मी का है। पहले संस्करण के कुछ उद्धरण (मेरे काम पर दूसरा):

  • त्रुटि कोड वापस न करें
  • त्रुटि कोड को आसानी से अनदेखा किया जा सकता है, और अक्सर होता है।
  • अपवाद फ्रेमवर्क में त्रुटियों की रिपोर्ट करने का प्राथमिक साधन हैं।
  • अंगूठे का एक अच्छा नियम यह है कि यदि कोई विधि ऐसा नहीं करती है जो उसका नाम बताता है, तो इसे एक विधि-स्तर की विफलता माना जाना चाहिए, जिसके परिणामस्वरूप अपवाद होगा।
  • यदि संभव हो तो नियंत्रण के सामान्य प्रवाह के अपवादों का उपयोग करें।

अपवादों के लाभ (एपीआई स्थिरता, त्रुटि हैंडलिंग कोड के स्थान का चुनाव, बेहतर मजबूती आदि) पर नोटों के पृष्ठ हैं। प्रदर्शन पर एक अनुभाग है जिसमें कई पैटर्न (टेस्टर-डोअर, ट्राय-पार्स) शामिल हैं।

अपवाद और अपवाद हैंडलिंग खराब नहीं हैं । किसी भी अन्य सुविधा की तरह, उनका दुरुपयोग किया जा सकता है।


4
मुझे उस पर असहमत होना पड़ेगा। मैं अपवादों के खिलाफ नहीं हूं, और यह पुस्तक एक होना चाहिए, हालांकि यह .NET विकास और C # के पक्षपाती है।

3
मुझे पता है कि यह प्राचीन है, बस यह टिप्पणी करना चाहता था कि ऐसा लगता है कि .NET प्रकार और * निक्स प्रकार के बीच एक सामान्य शैली असहमति होगी। मेरे द्वारा उपयोग किए गए सभी पुस्तकालयों में लिनक्स देव उपयोग रिटर्न कोड, और * मैंने पढ़ा है (जैसे मेरी कंपनी और Google के उदाहरण के लिए) निक्स शैली मार्गदर्शक बस "हम अपवाद नहीं करते हैं" कहते हैं। जरा सोचिए यह दिलचस्प है।
जर्विस्टेव जूल

1
फ़्रेमवर्क को अपवाद उपयोगकर्ता अनुप्रयोगों से अलग तरीके से व्यवहार करना चाहिए। फ़्रेमवर्क में अपवाद को फेंकने के अलावा अन्य त्रुटियों से निपटने का कोई तरीका नहीं है, उपभोक्ता आवेदन करते हैं।
0x6C38

11

गोलंग के दृष्टिकोण से, मुझे लगता है कि अपवाद हैंडलिंग नहीं होने से संकलन प्रक्रिया सरल और सुरक्षित रहती है।

लिनुस के दृष्टिकोण से, मैं समझता हूं कि कर्नेल कोड सभी कोने के मामलों के बारे में है। तो यह अपवादों को मना करने के लिए समझ में आता है।

अपवाद कोड में समझ में आता है कि फर्श पर वर्तमान कार्य को छोड़ना ठीक था, और जहां सामान्य मामला कोड में त्रुटि से अधिक महत्व है। लेकिन उन्हें संकलक से कोड पीढ़ी की आवश्यकता होती है।

उदाहरण के लिए, वे अधिकांश उच्च-स्तरीय, उपयोगकर्ता-सामना करने वाले कोड, जैसे वेब और डेस्कटॉप एप्लिकेशन कोड में ठीक हैं।


लेकिन कर्नेल कोड के लिए जो सच है वह लंबे समय तक चलने वाली देशी सर्वर प्रक्रियाओं के लिए भी सही है।
लोथेर

11

अपने आप में अपवाद "बुरा" नहीं है, यह ऐसा तरीका है कि अपवाद कभी-कभी संभाले जाते हैं जो बुरे होते हैं। ऐसे कई दिशानिर्देश हैं जो इन मुद्दों में से कुछ को कम करने में मदद करने के लिए अपवादों को संभालने पर लागू किए जा सकते हैं। इनमें से कुछ शामिल हैं (लेकिन निश्चित रूप से सीमित नहीं हैं):

  1. कार्यक्रम प्रवाह को नियंत्रित करने के लिए अपवादों का उपयोग न करें - अर्थात तर्क के प्रवाह को बदलने के लिए "पकड़" बयानों पर भरोसा न करें। न केवल यह तर्क के आसपास विभिन्न विवरणों को छिपाने के लिए करता है, यह खराब प्रदर्शन का कारण बन सकता है।
  2. किसी फ़ंक्शन के भीतर से अपवादों को न फेंकें जब एक लौटाया गया "स्थिति" अधिक समझ में आता है - केवल अपवाद को असाधारण स्थिति में फेंक दें। अपवाद बनाना एक महंगा, प्रदर्शन-गहन ऑपरेशन है। उदाहरण के लिए, यदि आप किसी फ़ाइल को खोलने के लिए कोई विधि कहते हैं और वह फ़ाइल मौजूद नहीं है, तो "FileNotFound" अपवाद को फेंक दें। यदि आप ऐसी विधि कहते हैं जो यह निर्धारित करती है कि ग्राहक खाता मौजूद है, तो बूलियन मान लौटाएँ, "CustomerNotFound" अपवाद न लौटें।
  3. यह निर्धारित करते समय कि अपवाद को संभालना है या नहीं, एक "कोशिश ... पकड़" खंड का उपयोग न करें जब तक कि आप अपवाद के साथ कुछ उपयोगी न कर सकें। यदि आप अपवाद को संभालने में सक्षम नहीं हैं, तो आपको इसे कॉल स्टैक को बबल करने देना चाहिए। अन्यथा, अपवाद हैंडलर द्वारा "निगला हुआ" हो सकता है और विवरण खो जाएगा (जब तक कि आप अपवाद को फिर से नहीं हटाते)।

2
स्टेटस लौटाना एक मुश्किल काम है। मैंने अभी तक बहुत अधिक कोड देखा है जिसमें गेटकॉस्टर विधि है जो ग्राहक इकाई को सफलता पर लौटाता है या विफलता पर अशक्त है। कई मामलों में कॉलिंग कोड ने कभी भी परिणाम की जांच नहीं की, लेकिन तुरंत ग्राहक तक पहुंच बनाई। इसने अधिकांश समय काम किया ...
TrueWill

3
लेकिन अगर GetCustomer अशक्त लौटने के बजाय एक अपवाद फेंकता है, तो क्लाइंट कोड को अभी भी अपवाद को संभालने की आवश्यकता है। चाहे वह अशक्त के लिए जाँच करके हो या अपवादों को संभालने से, ज़िम्मेदारी क्लाइंट कोड के साथ होती है - अगर यह ठीक से काम नहीं करता है, तो या तो जल्द ही या बाद में कुछ विस्फोट होगा।
क्रिस

1
@TrueWill भाषाएँ जो टेम्प्लेट / जेनरिक का समर्थन करती हैं Option<T>, nullआजकल के बजाय वापस लौटकर इसे हल करती हैं। बस उदाहरण के लिए जावा 8 में पेश किया गया, अमरूद (और अन्य) से एक संकेत ले रहा है।
मार्टेन बॉड्यूस

@owlstead हां। शायद मोनद से प्यार करो। अगर आपकी भाषा इसका समर्थन करती है और पैटर्न मिलान प्रदान करती है तो यह एक अच्छा तरीका है।
ट्रूविल

@owlstead फिर, क्रिस ने जो कहा वह अभी भी इसके लिए मजबूत है - उपयोगकर्ता को .orElse (defaultObject) फ़ंक्शन को कॉल करने के लिए याद रखना होगा, या जो भी प्रश्न में भाषा का मुहावरा तय किया है। दिन के अंत में यह प्रोग्रामर है जो त्रुटि समस्या विधि के बजाय समस्या है।
छत्र

9

विशिष्ट तर्क हैं कि यह बताने का कोई तरीका नहीं है कि किसी विशेष कोड (भाषा के आधार पर) से क्या अपवाद निकलेंगे और वे बहुत अधिक gotoएस जैसे हैं , जिससे मानसिक रूप से निष्पादन को मुश्किल बना दिया जाता है।

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

इस मुद्दे पर निश्चित रूप से कोई सहमति नहीं है। मैं कहूंगा कि लाइनस जैसे हार्ड-कोर सी प्रोग्रामर के दृष्टिकोण से, अपवाद निश्चित रूप से एक बुरा विचार है। एक विशिष्ट जावा प्रोग्रामर एक बहुत अलग स्थिति में है, हालांकि।


1
सी कोड में अपवाद हैं, बस एक अलग तरीके से। आपको हर कॉल को गैर-तुच्छ कार्य में लपेटना होगा, यदि वह उस भाषा का उपयोग सिरदर्द करता है!
2

1
वहाँ भी setjmp/ longjmpसामान है, जो बहुत बुरा है।
टिम सिल्वेस्टर

9
क्या आप वास्तव में एक ऐसे व्यक्ति की सलाह लेना चाहते हैं जो डक्ट टेप प्रोग्रामर को महत्व देता है और जो यह नहीं मानता है कि यूनिट परीक्षण आवश्यक हैं? joelonsoftware.com/items/2009/09/23.html
TrueWill

4
यह एक चर्चा में क्लासिक गलती (या धोखा) है जहां विषय पर तर्क को व्यक्तित्व संदर्भों के साथ बदल दिया जाता है। यह आम तौर पर पतित चर्चा का संकेत है।
पेट्र ग्लैडिख

1
@PetrGladkikh लाइनस की राय का जिक्र करते हुए ओपी के साथ चर्चा शुरू हुई ... यह धोखा प्राधिकरण को अपील की गिरावट के रूप में जाना जाता है। चर्चा केवल वहां से ऊपर जा सकती है, और यह इस सवाल का जवाब देने के लिए कोई "धोखा" नहीं है कि लिनुस को उनके व्यक्तित्व का हवाला देकर अपवाद क्यों पसंद नहीं है।
जिम बाल्टर

7

अपवाद बुरे नहीं हैं। वे C ++ के RAII मॉडल के साथ अच्छी तरह से फिट होते हैं, जो C ++ के बारे में सबसे सुंदर बात है। यदि आपके पास कोड का एक गुच्छा पहले से ही सुरक्षित नहीं है, तो वे उस संदर्भ में खराब हैं। यदि आप वास्तव में निम्न स्तर के सॉफ्टवेयर लिख रहे हैं, जैसे कि लिनक्स ओएस, तो वे खराब हैं। यदि आपको अपने कोड को त्रुटि रिटर्न चेक के एक समूह के साथ डालना पसंद है, तो वे सहायक नहीं हैं। यदि आपके पास अपवाद को फेंकने पर संसाधन नियंत्रण की कोई योजना नहीं है (जो कि C ++ विध्वंसक प्रदान करता है) तो वे खराब हैं।


7
आरएआई अपवाद के बिना भी उपयोगी है।
मार्क रैनसम

4
हालांकि, अपवाद RAII (या कुछ अन्य स्वचालित संसाधन प्रबंधन) के बिना उपयोगी नहीं हैं।
ग्रेग रोजर्स

उन स्थितियों को इंगित करने के लिए +1 जहां अपवाद उचित नहीं हैं और अपवाद स्वाभाविक रूप से खराब नहीं हैं।
चरण

4

अपवादों के लिए एक महान उपयोग-मामला इस प्रकार है ...।

कहते हैं कि आप एक परियोजना पर हैं और प्रत्येक नियंत्रक (लगभग 20 अलग-अलग प्रमुख) एक क्रिया विधि के साथ एक एकल सुपरक्लास नियंत्रक का विस्तार करते हैं। फिर हर कंट्रोलर एक दूसरे केस में B, C, D को एक-दूसरे को कॉल करने वाले सामान से अलग करता है और दूसरे केस में F, G, D। अपवाद यहां कई मामलों में बचाव में आते हैं जहां कई टन रिटर्न कोड था और हर नियंत्रक इसे अलग तरीके से संभाल रहा था। मैंने उस सभी कोड को मिटा दिया, "डी" से उचित अपवाद को फेंक दिया, इसे सुपरक्लास नियंत्रक एक्शन विधि में पकड़ा और अब हमारे सभी नियंत्रक सुसंगत हैं। पहले D, MULTIPLE के लिए अलग-अलग त्रुटि मामलों के लिए अशक्त लौट रहा था, जिसके बारे में हम अंत-उपयोगकर्ता को बताना चाहते हैं, लेकिन मैं और मैं नहीं कर सका

हां, हमें प्रत्येक स्तर और किसी भी संसाधन सफाई / लीक के बारे में चिंता करनी होगी, लेकिन सामान्य तौर पर हमारे नियंत्रकों में से किसी के पास सफाई करने के लिए कोई संसाधन नहीं थे।

भगवान का शुक्र है कि हमारे पास कुछ अपवाद थे या मैं एक विशाल रिफ्लेक्टर के लिए था और एक साधारण प्रोग्रामिंग समस्या होने पर किसी चीज़ पर बहुत समय बर्बाद करना चाहिए।


1
+1 आसानी से मेरे द्वारा पढ़े गए अपवादों का उपयोग करने के लिए सबसे अच्छे तर्कों में से एक। अधिक विस्तृत उदाहरण (यानी एक यूएमएल आरेख, कुछ स्यूडोकोड या कुछ वास्तविक कोड) का उपयोग किया जा सकता था, लेकिन उपवर्गों को लगातार बनाने के बारे में बात एक अच्छी है। इसके अलावा, तथ्य यह है कि आपके साक्ष्य एक वास्तविक संकेत है कि अपवाद वास्तविक स्थितियों में उपयोगी हैं, और उपयोगिता किसी भी भाषा की विशेषता का मुख्य उद्देश्य है।
चरण

एक अतिरिक्त के रूप में, यदि आप स्काला में हैं, तो आप इसके बजाय कोशिश कर सकते हैं [रिस्पांस टाइप] जो अपवाद या वास्तविक प्रतिक्रिया का प्रतिनिधित्व करता है। इसके बाद आप उसी पैटर्न का पालन कर सकते हैं जिसे मैं वास्तविक अपवादों के बिना ऊपर कर रहा हूं, इसके अलावा वे कोशिश में लगाए गए हैं। फिर यह हर विधि की तरह है जिसमें आपके पास 1 + एन प्रतिक्रिया प्रकार हैं जो मुझे लगता है कि आवश्यक है। हालांकि हम भविष्य में वापसी [प्रतिक्रिया] जो कोशिश की तरह काम करते हैं, लेकिन अधिक अतुल्यकालिक प्रोग्रामिंग के साथ मदद कर सकते हैं।
डीन हिलर

2

सैद्धांतिक रूप से वे वास्तव में बुरे हैं। सही गणितीय दुनिया में आप अपवाद स्थितियों को प्राप्त नहीं कर सकते। कार्यात्मक भाषाओं को देखें, तो उनका कोई साइड इफेक्ट नहीं है, इसलिए उनके पास वास्तव में अलौकिक स्थितियों के लिए स्रोत नहीं है।

लेकिन, वास्तविकता एक और कहानी है। हमारे पास हमेशा ऐसी स्थितियां होती हैं जो "अप्रत्याशित" होती हैं। यही कारण है कि हमें अपवादों की आवश्यकता है।

मुझे लगता है कि हम अपवाद के रूप में अपवाद के बारे में सोच सकते हैं ExceptionSituationObserver के लिए चीनी। आपको केवल अपवादों की सूचनाएं मिलती हैं। और कुछ नहीं।

गो के साथ, मुझे लगता है कि वे कुछ ऐसा करेंगे जो "अप्रत्याशित" स्थितियों से निपटेंगे। मैं अनुमान लगा सकता हूं कि वे इसे अपवाद के रूप में कम विनाशकारी और अनुप्रयोग तर्क के रूप में अधिक ध्वनि बनाने की कोशिश करेंगे। लेकिन यह सिर्फ मेरा अनुमान है।


2
"कार्यात्मक भाषाओं को देखें, तो उनका कोई साइड इफेक्ट नहीं है, इसलिए उनके पास वास्तव में अलौकिक स्थितियों के लिए स्रोत नहीं है।" वह स्थूल अधिपति है।
स्टीफन सी

3
गणित में 5/0 क्या है? Arcsin (200)? Sqrt (-1)? मठ में असाधारण स्थितियों का भार है।
रॉबर्ट फ्रेजर

3
यह निष्पादनात्मक स्थिति नहीं है ... उनका कोई मतलब नहीं है ... और उस कारण को अपवाद के रूप में लागू किया जा सकता है ... लेकिन यह पूर्व शर्त की शीशी के रूप में भी लागू किया जा सकता है .. इसलिए यह तकनीकी कार्यान्वयन पर निर्भर करता है।
माइक चालि

3
@ मायकेचेली - मुझे खेद है, लेकिन यह सिर्फ एक ही है। आप इस तरह के तर्क को लागू करने के लिए कह सकते हैं कि किसी भी चीज में कोई अपवाद स्थितियां नहीं हैं, कभी भी। वास्तव में, गणितीय अभिव्यक्तियाँ जिनका कोई अर्थ नहीं है (या जिनका कोई निश्चित मूल्य नहीं है) असाधारण हैं। इसका मतलब यह नहीं है कि उन्हें अपवादों को फेंकने और पकड़ने से निपटने की जरूरत है ... लेकिन यदि आप ऐसा नहीं करते हैं, तो आपको या तो विशेष मान (जैसे कि इन्फ और नेन) या कई मान वापस करने वाले ऑपरेशन की आवश्यकता है। संक्षेप में, इन मामलों में किसी प्रकार के विशेष उपचार की आवश्यकता होती है
स्टीफन सी

1
कंप्यूटर राज्य मशीनें हैं। एक आदर्श गणित की दुनिया नहीं।
अरुणव सान्याल

1

C ++ का अपवाद-हैंडलिंग प्रतिमान, जो जावा के लिए आंशिक आधार बनाता है, और बदले में .net, कुछ अच्छी अवधारणाओं का परिचय देता है, लेकिन कुछ गंभीर सीमाएँ भी हैं। अपवाद से निपटने के प्रमुख डिजाइन इरादों में से एक यह है कि वे यह सुनिश्चित करने के लिए तरीकों की अनुमति दें कि वे अपनी पोस्ट-शर्तों को संतुष्ट करेंगे या एक अपवाद को फेंक देंगे, और यह भी सुनिश्चित करेंगे कि किसी भी क्लीनअप को विधि से बाहर निकलने से पहले होने की आवश्यकता होगी। दुर्भाग्य से, C ++, Java, और .net के अपवाद-हैंडलिंग प्रतिमान स्थिति को संभालने के किसी भी अच्छे साधन प्रदान करने में विफल रहते हैं जहां अप्रत्याशित कारक अपेक्षित क्लीनअप को रोकने से रोकते हैं। बदले में इसका मतलब है कि अगर किसी को कुछ अप्रत्याशित होता है, तो उसे जोखिम में पड़ना चाहिए, अगर कुछ अनपेक्षित होता है (स्टैक अनइंडिंग के दौरान अपवाद को संभालने के लिए C ++ दृष्टिकोण)

यहां तक ​​कि अगर अपवाद हैंडलिंग आम तौर पर अच्छा होगा, तो यह अस्वीकार्य नहीं है क्योंकि अस्वीकार्य अपवाद-अपवाद प्रतिमान है जो अन्य समस्याओं के बाद सफाई करते समय होने वाली समस्याओं से निपटने के लिए एक अच्छा साधन प्रदान करने में विफल रहता है। यह कहना नहीं है कि एक फ्रेमवर्क एक अपवाद-हैंडलिंग प्रतिमान के साथ डिज़ाइन नहीं किया जा सकता है जो कई-विफलता परिदृश्यों में भी समझदार व्यवहार सुनिश्चित कर सकता है, लेकिन शीर्ष भाषाओं या रूपरेखाओं में से कोई भी अभी तक ऐसा नहीं कर सकता है।


1

मैं अन्य सभी उत्तरों को पढ़ता हूं, इसलिए इस महा याव का पहले ही उल्लेख किया जा चुका है, लेकिन एक आलोचना यह है कि वे कार्यक्रमों को लंबी श्रृंखलाओं में तोड़ने का कारण बनते हैं, जिससे कोड को डीबग करते समय त्रुटियों को ट्रैक करना मुश्किल हो जाता है। उदाहरण के लिए, यदि फू () कॉल बार () जिसे वाह () कहता है जो टोस्ट्रिंग () को कॉल करता है, तो गलती से गलत डेटा को टोस्ट्रिंग () में धकेल देता है, फू () में एक त्रुटि की तरह लग रहा है, लगभग एक पूरी तरह से असंबंधित फ़ंक्शन।


0
  • अपवाद संभाला नहीं जा रहा है आमतौर पर बुरा है।
  • बुरी तरह से संभाला अपवाद (निश्चित रूप से) बुरा है।
  • अपवाद से निपटने की 'अच्छाई / बुराई' संदर्भ / गुंजाइश और उपयुक्तता पर निर्भर करती है, और ऐसा करने के लिए नहीं।

0

ठीक है, उबाऊ जवाब यहाँ। मुझे लगता है कि यह वास्तव में भाषा पर निर्भर करता है। जहां एक अपवाद आवंटित संसाधनों को पीछे छोड़ सकता है, उन्हें बचा जाना चाहिए। स्क्रिप्टिंग भाषाओं में वे आवेदन प्रवाह के कुछ हिस्सों को सिर्फ रेगिस्तान या ओवरजंप करते हैं। यह अपने आप में नापसंद है, फिर भी अपवादों के साथ निकट-घातक त्रुटियों से बचना एक स्वीकार्य विचार है।

त्रुटि-सिग्नलिंग के लिए मैं आमतौर पर त्रुटि संकेतों को प्राथमिकता देता हूं। सभी एपीआई पर निर्भर करता है, केस और गंभीरता का उपयोग करें, या यदि लॉगिंग पर्याप्त है। इसके अलावा मैं व्यवहार को फिर से परिभाषित करने की कोशिश कर रहा हूं throw Phonebooks()। यह विचार कि "अपवाद" अक्सर मृत अंत होते हैं, लेकिन "फोनबुक" में त्रुटि सुधार या वैकल्पिक निष्पादन मार्गों पर उपयोगी जानकारी होती है। (अभी तक एक अच्छा उपयोग मामला नहीं मिला, लेकिन कोशिश करते रहें।)


0

मेरे लिए यह मुद्दा बहुत सरल है। कई प्रोग्रामर अपवाद हैंडलर का अनुचित तरीके से उपयोग करते हैं। अधिक भाषा संसाधन बेहतर है। अपवादों को संभालने में सक्षम होना अच्छा है। खराब उपयोग का एक उदाहरण एक ऐसा मूल्य है जिसे पूर्णांक सत्यापित नहीं किया जाना चाहिए, या एक और इनपुट जिसे विभाजित किया जा सकता है और शून्य के विभाजन के लिए जांच नहीं की जा सकती ... अपवाद हैंडलिंग अधिक काम और कठिन सोच से बचने का एक आसान तरीका हो सकता है, प्रोग्रामर गंदे शॉर्टकट करना और अपवाद को लागू करना चाहते हो सकता है ... कथन: "एक पेशेवर कोड कभी भी विफल नहीं होता" भ्रम हो सकता है, अगर एल्गोरिथम द्वारा संसाधित किए गए कुछ मुद्दे अपने स्वयं के स्वभाव से अनिश्चित हैं। शायद प्रकृति द्वारा अज्ञात परिस्थितियों में अपवाद हैंडलर खेलना अच्छा है। अच्छी प्रोग्रामिंग प्रैक्टिस बहस का विषय है।


मुद्दा यह नहीं है (या नहीं होना चाहिए) कि क्या कोड विफल हो सकता है - एक बड़ा मुद्दा यह है कि किस हद तक, यदि कोड विफल होता है, तो कोई व्यक्ति विशेष के बारे में परवाह करता है। यदि कोई दस्तावेज़ को लोड करने की कोशिश करता है और "रीड डेटा" विधियों में से एक विफल हो जाता है, तो एक अक्सर वास्तव में परवाह नहीं करता है, क्योंकि प्रभाव समान रूप से एक ही है: दस्तावेज़ लोड नहीं किया जा सकता है। वैचारिक रूप से, अपवाद हैंडलिंग उसके लिए अच्छा होना चाहिए। समस्या यह है कि .NET और जावा के अपवाद-हैंडलिंग प्रतिमान "बोरिंग" अपवादों को अलग करने का कोई अच्छा तरीका प्रदान नहीं करते हैं, जिन्हें एक साथ लंप किया जाना चाहिए, जो नहीं करना चाहिए।
सुपरकाट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.