Google की गो भाषा में डिज़ाइन पसंद के रूप में कोई अपवाद नहीं है, और लिनक्स प्रसिद्धि के लिनस ने अपवादों को बकवास कहा है। क्यों?
Google की गो भाषा में डिज़ाइन पसंद के रूप में कोई अपवाद नहीं है, और लिनक्स प्रसिद्धि के लिनस ने अपवादों को बकवास कहा है। क्यों?
जवाबों:
अपवादों को कोड लिखना वास्तव में आसान होता है, जहां एक अपवाद को फेंक दिया जाता है, जो आक्रमणकारियों को तोड़ देगा और वस्तुओं को असंगत स्थिति में छोड़ देगा। वे अनिवार्य रूप से आपको यह याद रखने के लिए मजबूर करते हैं कि आपके द्वारा दिया गया प्रत्येक कथन संभावित रूप से फेंक सकता है, और सही ढंग से संभाल सकता है। ऐसा करना मुश्किल और जवाबी हो सकता है।
एक साधारण उदाहरण के रूप में इस तरह से कुछ पर विचार करें:
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 ++ में अपवाद सुरक्षित कोडिंग के बारे में पूरी किताबें लिखी गई हैं। बहुत सारे विशेषज्ञों ने इसे गलत माना है। यदि यह वास्तव में जटिल है और इसमें बहुत सारी बारीकियाँ हैं, तो शायद यह एक अच्छा संकेत है कि आपको उस सुविधा को अनदेखा करने की आवश्यकता है। :-)
गो भाषा के डिज़ाइन में अपवाद नहीं होने का कारण बताया गया है:
अपवाद एक ऐसी ही कहानी है। अपवादों के लिए कई डिजाइन प्रस्तावित किए गए हैं, लेकिन प्रत्येक भाषा और रन-टाइम के लिए महत्वपूर्ण जटिलता जोड़ता है। उनके स्वभाव से, अपवाद कार्य और शायद गोरोइटिन भी; उनके व्यापक प्रभाव हैं। पुस्तकालयों पर उनके प्रभाव के बारे में भी चिंता है। वे परिभाषा के अनुसार, अन्य भाषाओं के साथ असाधारण अभी तक का अनुभव है जो उनका समर्थन करते हैं जो दिखाते हैं कि वे पुस्तकालय और इंटरफ़ेस विनिर्देश पर गहरा प्रभाव डालते हैं। ऐसा डिज़ाइन ढूंढना अच्छा होगा जो उन्हें विशेष नियंत्रण प्रवाह में बदलने के लिए आम त्रुटियों को प्रोत्साहित किए बिना वास्तव में असाधारण होने की अनुमति देता है जिसकी क्षतिपूर्ति करने के लिए प्रत्येक प्रोग्रामर की आवश्यकता होती है।
जेनेरिक की तरह, अपवाद एक खुला मुद्दा है।
दूसरे शब्दों में, उन्होंने अभी तक यह पता नहीं लगाया है कि गो को अपवाद के रूप में कैसे समर्थन दिया जाए, जो उन्हें लगता है कि संतोषजनक है। वे यह नहीं कह रहे हैं कि अपवाद प्रति खराब हैं ;
अद्यतन - मई २०१२
गो डिजाइनर अब बंद बाड़ पर चढ़ गए हैं। उनके FAQ अब यह कहते हैं:
हम मानते हैं कि एक नियंत्रण संरचना के लिए युग्मन अपवाद, जैसा कि ट्राइ-कैच-आखिर मुहावरे में है, परिणामी कोड में। यह प्रोग्रामर को बहुत सी साधारण त्रुटियों को लेबल करने के लिए प्रोत्साहित करने के लिए भी प्रेरित करता है, जैसे कि एक फ़ाइल को खोलने में विफल होना, असाधारण के रूप में।
गो एक अलग दृष्टिकोण लेता है। सादे त्रुटि हैंडलिंग के लिए, गो के बहु-मूल्य रिटर्न रिटर्न मूल्य को ओवरलोड किए बिना एक त्रुटि की रिपोर्ट करना आसान बनाते हैं। गो की अन्य विशेषताओं के साथ युग्मित एक कैनोनिकल त्रुटि प्रकार, त्रुटि को अन्य भाषाओं में सुखद लेकिन काफी अलग बनाता है।
गो में कुछ अंतर्निहित कार्यों को संकेत देने और वास्तव में असाधारण स्थितियों से उबरने के लिए भी है। पुनर्प्राप्ति तंत्र को एक फ़ंक्शन के राज्य के एक भाग के रूप में केवल एक त्रुटि के बाद फाड़ दिया जाता है, जो तबाही को संभालने के लिए पर्याप्त है, लेकिन इसके लिए कोई अतिरिक्त नियंत्रण संरचनाओं की आवश्यकता नहीं होती है और जब अच्छी तरह से उपयोग किया जाता है, तो स्वच्छ त्रुटि-हैंडलिंग कोड हो सकता है।
जानकारी के लिए Defer, Panic और Recover लेख देखें।
तो संक्षिप्त उत्तर यह है कि वे बहु-मूल्य वापसी का उपयोग करके इसे अलग तरीके से कर सकते हैं। (और उनके पास वैसे भी अपवाद रूप से निपटने का एक तरीका है)
... और लिनक्स प्रसिद्धि के लिनस ने अपवाद बकवास कहा है।
यदि आप यह जानना चाहते हैं कि लिनुस अपवाद क्यों सोचते हैं, तो यह बकवास है, सबसे अच्छी बात यह है कि इस विषय पर उनके लेखन की तलाश करें। केवल एक चीज जो मैंने अभी तक ट्रैक की है, वह यह उद्धरण है जो C ++ पर ईमेल के एक जोड़े में एम्बेडेड है :
"पूरे सी ++ अपवाद को संभालने वाली चीज़ मौलिक रूप से टूटी हुई है। यह विशेष रूप से गुठली के लिए टूटी हुई है।"
आप ध्यान दें कि वह विशेष रूप से C ++ अपवादों के बारे में बात कर रहा है, और सामान्य रूप से अपवाद नहीं। (और सी ++ अपवाद करते हैं जाहिरा तौर पर कुछ मुद्दों है कि उन्हें मुश्किल सही ढंग से उपयोग करने के लिए बनाते हैं।)
मेरा निष्कर्ष यह है कि लिनस ने अपवादों को नहीं बुलाया है (सामान्य रूप से) "बकवास" बिल्कुल नहीं!
अपवाद प्रति से खराब नहीं हैं, लेकिन अगर आप जानते हैं कि वे बहुत कुछ होने जा रहे हैं, तो वे प्रदर्शन के मामले में महंगे हो सकते हैं।
अंगूठे का नियम यह है कि अपवादों को असाधारण परिस्थितियों को चिह्नित करना चाहिए, और यह कि आपको उन्हें कार्यक्रम के प्रवाह के नियंत्रण के लिए उपयोग नहीं करना चाहिए।
मैं "केवल असाधारण स्थिति में अपवादों को फेंकने" से असहमत हूं। जबकि आम तौर पर सच है, यह भ्रामक है। अपवाद त्रुटि स्थितियों (निष्पादन विफलताओं) के लिए हैं।
आपके द्वारा उपयोग की जाने वाली भाषा के बावजूद, फ्रेमवर्क डिज़ाइन दिशानिर्देशों की एक प्रति चुनें : कन्वेंशन, मुहावरे, और पुन: प्रयोज्य .NET लाइब्रेरीज़ (2 डी संस्करण) के लिए पैटर्न। अपवाद फेंकने का अध्याय बिना सहकर्मी का है। पहले संस्करण के कुछ उद्धरण (मेरे काम पर दूसरा):
अपवादों के लाभ (एपीआई स्थिरता, त्रुटि हैंडलिंग कोड के स्थान का चुनाव, बेहतर मजबूती आदि) पर नोटों के पृष्ठ हैं। प्रदर्शन पर एक अनुभाग है जिसमें कई पैटर्न (टेस्टर-डोअर, ट्राय-पार्स) शामिल हैं।
अपवाद और अपवाद हैंडलिंग खराब नहीं हैं । किसी भी अन्य सुविधा की तरह, उनका दुरुपयोग किया जा सकता है।
गोलंग के दृष्टिकोण से, मुझे लगता है कि अपवाद हैंडलिंग नहीं होने से संकलन प्रक्रिया सरल और सुरक्षित रहती है।
लिनुस के दृष्टिकोण से, मैं समझता हूं कि कर्नेल कोड सभी कोने के मामलों के बारे में है। तो यह अपवादों को मना करने के लिए समझ में आता है।
अपवाद कोड में समझ में आता है कि फर्श पर वर्तमान कार्य को छोड़ना ठीक था, और जहां सामान्य मामला कोड में त्रुटि से अधिक महत्व है। लेकिन उन्हें संकलक से कोड पीढ़ी की आवश्यकता होती है।
उदाहरण के लिए, वे अधिकांश उच्च-स्तरीय, उपयोगकर्ता-सामना करने वाले कोड, जैसे वेब और डेस्कटॉप एप्लिकेशन कोड में ठीक हैं।
अपने आप में अपवाद "बुरा" नहीं है, यह ऐसा तरीका है कि अपवाद कभी-कभी संभाले जाते हैं जो बुरे होते हैं। ऐसे कई दिशानिर्देश हैं जो इन मुद्दों में से कुछ को कम करने में मदद करने के लिए अपवादों को संभालने पर लागू किए जा सकते हैं। इनमें से कुछ शामिल हैं (लेकिन निश्चित रूप से सीमित नहीं हैं):
Option<T>
, null
आजकल के बजाय वापस लौटकर इसे हल करती हैं। बस उदाहरण के लिए जावा 8 में पेश किया गया, अमरूद (और अन्य) से एक संकेत ले रहा है।
विशिष्ट तर्क हैं कि यह बताने का कोई तरीका नहीं है कि किसी विशेष कोड (भाषा के आधार पर) से क्या अपवाद निकलेंगे और वे बहुत अधिक goto
एस जैसे हैं , जिससे मानसिक रूप से निष्पादन को मुश्किल बना दिया जाता है।
http://www.joelonsoftware.com/items/2003/10/13.html
इस मुद्दे पर निश्चित रूप से कोई सहमति नहीं है। मैं कहूंगा कि लाइनस जैसे हार्ड-कोर सी प्रोग्रामर के दृष्टिकोण से, अपवाद निश्चित रूप से एक बुरा विचार है। एक विशिष्ट जावा प्रोग्रामर एक बहुत अलग स्थिति में है, हालांकि।
setjmp
/ longjmp
सामान है, जो बहुत बुरा है।
अपवाद बुरे नहीं हैं। वे C ++ के RAII मॉडल के साथ अच्छी तरह से फिट होते हैं, जो C ++ के बारे में सबसे सुंदर बात है। यदि आपके पास कोड का एक गुच्छा पहले से ही सुरक्षित नहीं है, तो वे उस संदर्भ में खराब हैं। यदि आप वास्तव में निम्न स्तर के सॉफ्टवेयर लिख रहे हैं, जैसे कि लिनक्स ओएस, तो वे खराब हैं। यदि आपको अपने कोड को त्रुटि रिटर्न चेक के एक समूह के साथ डालना पसंद है, तो वे सहायक नहीं हैं। यदि आपके पास अपवाद को फेंकने पर संसाधन नियंत्रण की कोई योजना नहीं है (जो कि C ++ विध्वंसक प्रदान करता है) तो वे खराब हैं।
अपवादों के लिए एक महान उपयोग-मामला इस प्रकार है ...।
कहते हैं कि आप एक परियोजना पर हैं और प्रत्येक नियंत्रक (लगभग 20 अलग-अलग प्रमुख) एक क्रिया विधि के साथ एक एकल सुपरक्लास नियंत्रक का विस्तार करते हैं। फिर हर कंट्रोलर एक दूसरे केस में B, C, D को एक-दूसरे को कॉल करने वाले सामान से अलग करता है और दूसरे केस में F, G, D। अपवाद यहां कई मामलों में बचाव में आते हैं जहां कई टन रिटर्न कोड था और हर नियंत्रक इसे अलग तरीके से संभाल रहा था। मैंने उस सभी कोड को मिटा दिया, "डी" से उचित अपवाद को फेंक दिया, इसे सुपरक्लास नियंत्रक एक्शन विधि में पकड़ा और अब हमारे सभी नियंत्रक सुसंगत हैं। पहले D, MULTIPLE के लिए अलग-अलग त्रुटि मामलों के लिए अशक्त लौट रहा था, जिसके बारे में हम अंत-उपयोगकर्ता को बताना चाहते हैं, लेकिन मैं और मैं नहीं कर सका
हां, हमें प्रत्येक स्तर और किसी भी संसाधन सफाई / लीक के बारे में चिंता करनी होगी, लेकिन सामान्य तौर पर हमारे नियंत्रकों में से किसी के पास सफाई करने के लिए कोई संसाधन नहीं थे।
भगवान का शुक्र है कि हमारे पास कुछ अपवाद थे या मैं एक विशाल रिफ्लेक्टर के लिए था और एक साधारण प्रोग्रामिंग समस्या होने पर किसी चीज़ पर बहुत समय बर्बाद करना चाहिए।
सैद्धांतिक रूप से वे वास्तव में बुरे हैं। सही गणितीय दुनिया में आप अपवाद स्थितियों को प्राप्त नहीं कर सकते। कार्यात्मक भाषाओं को देखें, तो उनका कोई साइड इफेक्ट नहीं है, इसलिए उनके पास वास्तव में अलौकिक स्थितियों के लिए स्रोत नहीं है।
लेकिन, वास्तविकता एक और कहानी है। हमारे पास हमेशा ऐसी स्थितियां होती हैं जो "अप्रत्याशित" होती हैं। यही कारण है कि हमें अपवादों की आवश्यकता है।
मुझे लगता है कि हम अपवाद के रूप में अपवाद के बारे में सोच सकते हैं ExceptionSituationObserver के लिए चीनी। आपको केवल अपवादों की सूचनाएं मिलती हैं। और कुछ नहीं।
गो के साथ, मुझे लगता है कि वे कुछ ऐसा करेंगे जो "अप्रत्याशित" स्थितियों से निपटेंगे। मैं अनुमान लगा सकता हूं कि वे इसे अपवाद के रूप में कम विनाशकारी और अनुप्रयोग तर्क के रूप में अधिक ध्वनि बनाने की कोशिश करेंगे। लेकिन यह सिर्फ मेरा अनुमान है।
C ++ का अपवाद-हैंडलिंग प्रतिमान, जो जावा के लिए आंशिक आधार बनाता है, और बदले में .net, कुछ अच्छी अवधारणाओं का परिचय देता है, लेकिन कुछ गंभीर सीमाएँ भी हैं। अपवाद से निपटने के प्रमुख डिजाइन इरादों में से एक यह है कि वे यह सुनिश्चित करने के लिए तरीकों की अनुमति दें कि वे अपनी पोस्ट-शर्तों को संतुष्ट करेंगे या एक अपवाद को फेंक देंगे, और यह भी सुनिश्चित करेंगे कि किसी भी क्लीनअप को विधि से बाहर निकलने से पहले होने की आवश्यकता होगी। दुर्भाग्य से, C ++, Java, और .net के अपवाद-हैंडलिंग प्रतिमान स्थिति को संभालने के किसी भी अच्छे साधन प्रदान करने में विफल रहते हैं जहां अप्रत्याशित कारक अपेक्षित क्लीनअप को रोकने से रोकते हैं। बदले में इसका मतलब है कि अगर किसी को कुछ अप्रत्याशित होता है, तो उसे जोखिम में पड़ना चाहिए, अगर कुछ अनपेक्षित होता है (स्टैक अनइंडिंग के दौरान अपवाद को संभालने के लिए C ++ दृष्टिकोण)
यहां तक कि अगर अपवाद हैंडलिंग आम तौर पर अच्छा होगा, तो यह अस्वीकार्य नहीं है क्योंकि अस्वीकार्य अपवाद-अपवाद प्रतिमान है जो अन्य समस्याओं के बाद सफाई करते समय होने वाली समस्याओं से निपटने के लिए एक अच्छा साधन प्रदान करने में विफल रहता है। यह कहना नहीं है कि एक फ्रेमवर्क एक अपवाद-हैंडलिंग प्रतिमान के साथ डिज़ाइन नहीं किया जा सकता है जो कई-विफलता परिदृश्यों में भी समझदार व्यवहार सुनिश्चित कर सकता है, लेकिन शीर्ष भाषाओं या रूपरेखाओं में से कोई भी अभी तक ऐसा नहीं कर सकता है।
मैं अन्य सभी उत्तरों को पढ़ता हूं, इसलिए इस महा याव का पहले ही उल्लेख किया जा चुका है, लेकिन एक आलोचना यह है कि वे कार्यक्रमों को लंबी श्रृंखलाओं में तोड़ने का कारण बनते हैं, जिससे कोड को डीबग करते समय त्रुटियों को ट्रैक करना मुश्किल हो जाता है। उदाहरण के लिए, यदि फू () कॉल बार () जिसे वाह () कहता है जो टोस्ट्रिंग () को कॉल करता है, तो गलती से गलत डेटा को टोस्ट्रिंग () में धकेल देता है, फू () में एक त्रुटि की तरह लग रहा है, लगभग एक पूरी तरह से असंबंधित फ़ंक्शन।
ठीक है, उबाऊ जवाब यहाँ। मुझे लगता है कि यह वास्तव में भाषा पर निर्भर करता है। जहां एक अपवाद आवंटित संसाधनों को पीछे छोड़ सकता है, उन्हें बचा जाना चाहिए। स्क्रिप्टिंग भाषाओं में वे आवेदन प्रवाह के कुछ हिस्सों को सिर्फ रेगिस्तान या ओवरजंप करते हैं। यह अपने आप में नापसंद है, फिर भी अपवादों के साथ निकट-घातक त्रुटियों से बचना एक स्वीकार्य विचार है।
त्रुटि-सिग्नलिंग के लिए मैं आमतौर पर त्रुटि संकेतों को प्राथमिकता देता हूं। सभी एपीआई पर निर्भर करता है, केस और गंभीरता का उपयोग करें, या यदि लॉगिंग पर्याप्त है। इसके अलावा मैं व्यवहार को फिर से परिभाषित करने की कोशिश कर रहा हूं throw Phonebooks()
। यह विचार कि "अपवाद" अक्सर मृत अंत होते हैं, लेकिन "फोनबुक" में त्रुटि सुधार या वैकल्पिक निष्पादन मार्गों पर उपयोगी जानकारी होती है। (अभी तक एक अच्छा उपयोग मामला नहीं मिला, लेकिन कोशिश करते रहें।)
मेरे लिए यह मुद्दा बहुत सरल है। कई प्रोग्रामर अपवाद हैंडलर का अनुचित तरीके से उपयोग करते हैं। अधिक भाषा संसाधन बेहतर है। अपवादों को संभालने में सक्षम होना अच्छा है। खराब उपयोग का एक उदाहरण एक ऐसा मूल्य है जिसे पूर्णांक सत्यापित नहीं किया जाना चाहिए, या एक और इनपुट जिसे विभाजित किया जा सकता है और शून्य के विभाजन के लिए जांच नहीं की जा सकती ... अपवाद हैंडलिंग अधिक काम और कठिन सोच से बचने का एक आसान तरीका हो सकता है, प्रोग्रामर गंदे शॉर्टकट करना और अपवाद को लागू करना चाहते हो सकता है ... कथन: "एक पेशेवर कोड कभी भी विफल नहीं होता" भ्रम हो सकता है, अगर एल्गोरिथम द्वारा संसाधित किए गए कुछ मुद्दे अपने स्वयं के स्वभाव से अनिश्चित हैं। शायद प्रकृति द्वारा अज्ञात परिस्थितियों में अपवाद हैंडलर खेलना अच्छा है। अच्छी प्रोग्रामिंग प्रैक्टिस बहस का विषय है।